Warning
This article was automatically translated by OpenAI (gpt-4o).It may be edited eventually, but please be aware that it may contain incorrect information at this time.
There are many common mistakes in configuring org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor, which is one of the most frequently used components of Spring's TaskScheduler.
corePoolSizemaxPoolSizequeueCapacity
These are the configuration items.
At first glance, it might seem that this Executor creates Threads in the following order:
- Create
Threadsup tocorePoolSizefirst - When
corePoolSizeis full, increaseThreadsup tomaxPoolSize - When
maxPoolSizeis exceeded, queue up toqueueCapacity - When
queueCapacityis exceeded, reject the request
However, this is a misunderstanding.
The correct order is:
- Create
Threadsup tocorePoolSize - When
corePoolSizeis full, queue up toqueueCapacity - When
queueCapacityis exceeded, increaseThreadsup tomaxPoolSize - When
maxPoolSizeis exceeded, reject the request
The default value for corePoolSize is 1, and the default values for both maxPoolSize and queueCapacity are Integer.MAX_VALUE.
The following configuration is meaningless:
@Bean
ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(4);
taskExecutor.setMaxPoolSize(40);
return taskExecutor;
}
Since queueCapacity is not set, the maximum number of threads is 4. All requests beyond that will be queued. The number 40 is meaningless.
@Bean
ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setMaxPoolSize(40);
return taskExecutor;
}
Since neither corePoolSize nor queueCapacity is set, the maximum number of threads is 1. All requests beyond that will be queued.
If you want to set the number of threads to 4-40, you need to configure it as follows (note that it does not create 4 threads initially):
@Bean
ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(4);
taskExecutor.setQueueCapacity(4);
taskExecutor.setMaxPoolSize(40);
return taskExecutor;
}
It is less confusing to recognize the configuration values in the following order:
corePoolSizequeueCapacitymaxPoolSize
Alternatively, if you only want to specify that the maximum number of threads is 40, you can do so as follows:
@Bean
ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(40);
return taskExecutor;
}
By the way, when creating the java.util.concurrent.ThreadPoolExecutor that ThreadPoolTaskExecutor delegates to, it is often used as follows:
ExecutorService executorService = Executors.newFixedThreadPool(40);
This is similar to:
@Bean
ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(40);
taskExecutor.setMaxPoolSize(40);
return taskExecutor;
}
When using Spring Boot, it is better to use AutoConfiguration rather than defining ThreadPoolTaskExecutor as above.
https://docs.spring.io/spring-boot/reference/features/task-execution-and-scheduling.html#page-title
In this case, you can set the pool size using the following properties:
spring.task.execution.pool.core-size=4
spring.task.execution.pool.queue-capacity=4
spring.task.execution.pool.max-size=40
If you intuitively want to increase Threads first, consider using riptide-concurrent as follows:
https://github.com/zalando/riptide/tree/main/riptide-concurrent