@Scheduled并发执行多个任务配置
项目中定义多个定时任务
@Component
@Slf4j
public class DynamicTask {
@Autowired
private DynamicTestMapper dynamicTestMapper;
@Scheduled(cron = "0 */1 * * * ?")
public void test() {
log.info("查询系统列表test");
List<Map<String, Object>> mapList = dynamicTestMapper.querySystemList();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("test数据大小:" + mapList.size());
}
@Scheduled(cron = "0 */1 * * * ?")
public void test1() {
log.info("查询系统列表test1");
List<Map<String, Object>> mapList = dynamicTestMapper.querySystemList();
log.info("test1数据大小:" + mapList.size());
}
}
从运行结果可以看到,两个定时任务是一个线程在执行,串行的。运行结果如下:
查看源码发现在项目启动的时候,ScheduledAnnotationBeanPostProcessor会执行finishRegistration方法,在spring容器中查找TaskScheduler和ScheduledExecutorService(java原生的)的bean,因为项目中未注入bean,这里获取的都是null值。
然后会执行ScheduledTaskRegistrar的scheduleTasks方法注册所有定时任务,在此方法内创建了一个newSingleThreadScheduledExecutor单线程的线程池,作为TaskScheduler的线程池。因此在执行定时任务的时候只有一个线程在串行化的执行所有任务。
因此,我们只需要自定义一个TaskScheduler,设置线程数即可。这里使用ThreadPoolTaskScheduler ,ThreadPoolTaskScheduler 的默认线程数也是1。
@Configuration
public class ScheduleConfig {
private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2 + 1;
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(CORE_POOL_SIZE);
return threadPoolTaskScheduler;
}
}
重新启动程序,可以看到自定义的TaskScheduler已经注入,且线程数为13。
运行结果: