---
title: Common Misconfigurations of ThreadPoolTaskExecutor
tags: ["Java", "Spring"]
categories: ["Programming", "Java", "org", "springframework", "scheduling", "concurrent"]
date: 2018-01-10T02:35:56Z
updated: 2023-06-08T05:28:32Z
---

> ⚠️ 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`](https://docs.spring.io/autorepo/docs/spring-framework/5.0.x/spring-framework-reference/integration.html#scheduling).

* `corePoolSize`
* `maxPoolSize`
* `queueCapacity`

These are the configuration items.

At first glance, it might seem that this `Executor` creates `Threads` in the following order:

1. Create `Threads` up to `corePoolSize` first
2. When `corePoolSize` is full, increase `Threads` up to `maxPoolSize`
3. When `maxPoolSize` is exceeded, queue up to `queueCapacity`
4. When `queueCapacity` is exceeded, reject the request

However, this is a misunderstanding.

The correct order is:

1. Create `Threads` up to `corePoolSize`
2. When `corePoolSize` is full, queue up to `queueCapacity`
3. When `queueCapacity` is exceeded, increase `Threads` up to `maxPoolSize`
4. When `maxPoolSize` is 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:

``` java
@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.

``` java
@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):

``` java
@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:

* `corePoolSize`
* `queueCapacity`
* `maxPoolSize`

Alternatively, if you only want to specify that the maximum number of threads is `40`, you can do so as follows:

``` java
@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:

``` java
ExecutorService executorService = Executors.newFixedThreadPool(40);
```

This is similar to:

``` java
@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:

```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:<br>
https://github.com/zalando/riptide/tree/main/riptide-concurrent
