52
votes

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.

5
Maybe this Spring documentation could help to solve your problem. - SubOptimal

5 Answers

72
votes

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.

33
votes

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.

2
votes

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);
        }
        ...
    }

1
votes

a very simple way to do this:

@Configuration
public class ScheduleConfig {
  ScheduleConfig(ThreadPoolTaskScheduler threadPoolTaskScheduler) {
    threadPoolTaskScheduler.setPoolSize(10);
  }
}
1
votes

Using built-in capabilities and with anotated spring configuration this will be like that:

    @Bean
    public TaskScheduler taskScheduler() {
        return new ConcurrentTaskScheduler(new ScheduledThreadPoolExecutor(20));
    }