我们在Java Scheduled定时任务中已经学到了如何开启定时任务,但却在同时开启多个定时任务的时候,遇到了新的问题,Scheduled定时任务是单线程的,无法满足同一个时间开启多个定时任务,因此,我们进行了如下调整:
1、新建一个配置类;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;@Configuration
@EnableAsyncpublic class AsyncConfig {private int corePoolSize = 10;private int maxPoolSize = 200;private int queueCapacity = 10;@Beanpublic Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(corePoolSize);executor.setMaxPoolSize(maxPoolSize);executor.setQueueCapacity(queueCapacity);executor.initialize();return executor;}
}
2、在定时任务中添加@Async异步注解,即可开启多线程定时任务。
但通过如上方法,又会出现新的问题,如果某个定时任务在规格的时间内没有运行完,而它新的定时任务再次开启,就会出现两个定时任务同时对表的数据进行操作,会导致数据各种的错误,因此,再次对定时任务进行处理,增加锁机制(synchronized),对未执行完的定时任务及时锁住,不让它开启下一个定时任务。
实例如下所示:
private static Object lkm1 = new Object();private static Object lkm2 = new Object();/**** @description:* @author: lkm* @date: 2023/9/7 9:15**/@Scheduled(cron = "0 0/1 * * * ?")public void scheduledTask1() throws Exception {synchronized(lkm1){Date date =new Date();System.out.println("====================任务开始1=================");System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));Thread.sleep(120000);//2分钟System.out.println("====================任务1,结束=================");}}/**** @description:* @author: lkm* @date: 2023/9/7 9:15**/@Scheduled(cron = "0 0/1 * * * ?")public void scheduledTask2() throws Exception {synchronized(lkm2){Date date =new Date();System.out.println("====================任务开始2=================");System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));Thread.sleep(120000);//2分钟System.out.println("====================任务2,结束=================");}}