基于一组配置,我的任务是每x分钟实例化一个计划任务列表,这些任务将基于CronTrigger执行。该实施的草稿版本与此类似:
for(Config cfg:configs){
Runnable task=()->doSomething(cfg);
taskScheduler.schedule(task,new CronTrigger("0 0/"+cfg.getScheduledTimeInMinutes()+" * * * *"));
}
taskScheduler
是一个bean,在当前类中自动装配,并在配置类中定义为:
@Bean
public TaskScheduler taskScheduler() {
return new ConcurrentTaskScheduler();
}
到目前为止,太好了。所有配置都会导致在计划的时间执行具有不同参数的相同方法。问题在于doSomething()
方法需要花费更多时间才能完成,并且下一个计划的任务应该触发,或者同时计划了多个任务。在这种情况下,发生的事情是执行不是异步的,并且每个任务都等待上一个任务完成。是否可以同时执行这些计划任务?我正在使用Java 8和Spring Boot 2.0。
答案 0 :(得分:1)
这一切都很好,您错过了一件小事情,或者说了一些关于在春季环境中执行计划任务的理解:
将此(添加到带@Configuration注释的类中)可以解决您的问题:
@Bean(destroyMethod = "shutdown")
public Executor taskScheduler() {
return Executors.newScheduledThreadPool(5); // 5 is arbitrary, change it to suit you
}
默认情况下,所有计划任务都使用1个线程来执行。如果需要更多控制权,则必须定义调度程序线程池。查找文档。
或者更好的方法:
@Configuration
public class SchedulingConfigurerConfiguration implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(100);
taskScheduler.initialize();
taskRegistrar.setTaskScheduler(taskScheduler);
}
}