Reputation: 1118
Based on a set of configurations, my task is to instantiate a list of scheduled tasks, to be executed based on a CronTrigger, every x minutes. A draft version of the implementation is similar to this:
for(Config cfg:configs){
Runnable task=()->doSomething(cfg);
taskScheduler.schedule(task,new CronTrigger("0 0/"+cfg.getScheduledTimeInMinutes()+" * * * *"));
}
The taskScheduler
is a bean, autowired in the current class, and defined in a config class as:
@Bean
public TaskScheduler taskScheduler() {
return new ConcurrentTaskScheduler();
}
So far, so good. All configs result in executing the same method, with different arguments, on scheduled time. The trouble is when a doSomething()
method takes more time to complete, and the next scheduled task should fire, or if there are more than one tasks scheduled at the same time. What happens in this case, is that execution is not async, and each task waits for the previous task to finish. Is is possible to achieve a concurrent execution of these scheduled tasks? I am using Java 8 and Spring Boot 2.0.
Upvotes: 1
Views: 725
Reputation: 947
Well that's all good, you are missing a small thing or lets say some understanding about execution of scheduled tasks in a spring environment:
Adding this (to your @Configuration annotated class) will fix your problem:
@Bean(destroyMethod = "shutdown")
public Executor taskScheduler() {
return Executors.newScheduledThreadPool(5); // 5 is arbitrary, change it to suit you
}
By default, all scheduled tasks use 1 thread to execute. and if you need more controll then you have to define the scheduler thread pool. Look up the docs.
Or a better way:
@Configuration
public class SchedulingConfigurerConfiguration implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(100);
taskScheduler.initialize();
taskRegistrar.setTaskScheduler(taskScheduler);
}
}
Upvotes: 1