What is the default scheduler pool size in spring-boot?
JavaSpringSpring BootJava Problem Overview
I'm using spring-boot
and @Scheduled
annotation to execute some tasks.
How can I find out what the default pool size of scheduled tasks is by default in spring-boot?
Reason: the following class does not execute the jobs in parallel, but one after the other. Maybe only a single thread executor is configured by default?
@Service
public class ZipFileTesterAsync {
@Scheduled(fixedDelay = 60000, initialDelay = 500)
public void run() throws Exception {
System.out.println("import 1");
TimeUnit.MINUTES.sleep(1);
System.out.println("import 1 finished");
}
@Scheduled(fixedDelay = 60000, initialDelay = 1000)
public void run2() throws Exception {
System.out.println("import 2");
TimeUnit.MINUTES.sleep(1);
}
}
Result: the 2nd job is executed after the first finished.
Java Solutions
Solution 1 - Java
Yes, all @Scheduled
methods share a single thread by default.
It is possible to override this behavior by defining a @Configuration
such as this:
@Configuration
public class SchedulingConfigurerConfiguration implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(100);
taskScheduler.initialize();
taskRegistrar.setTaskScheduler(taskScheduler);
}
}
This example ensures that all @Scheduled
methods share a thread pool of size 100.
Solution 2 - Java
The default pool size is 1, and you can set the pool size in application.properties
science springboot2.1.0 via changing the value of spring.task.scheduling.pool.size
.
spring.task.scheduling.pool.size=20
The same task will be executed in serialized when the trigger period is shorter than the execution duration. And Spring Boot will execute different tasks in parallel with a maximum of 20 threads.
Solution 3 - Java
The default scheduler pool size in spring-boot is only one.
In org.springframework.scheduling.config.ScheduledTaskRegistrar
:
/**
* Schedule all registered tasks against the underlying
* {@linkplain #setTaskScheduler(TaskScheduler) task scheduler}.
*/
@SuppressWarnings("deprecation")
protected void scheduleTasks() {
if (this.taskScheduler == null) {
this.localExecutor = Executors.newSingleThreadScheduledExecutor();
this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
}
...
}
Solution 4 - Java
a very simple way to do this:
@Configuration
public class ScheduleConfig {
ScheduleConfig(ThreadPoolTaskScheduler threadPoolTaskScheduler) {
threadPoolTaskScheduler.setPoolSize(10);
}
}
Solution 5 - Java
Using built-in capabilities and with anotated spring configuration this will be like that:
@Bean
public TaskScheduler taskScheduler() {
return new ConcurrentTaskScheduler(new ScheduledThreadPoolExecutor(20));
}