Implementing Asynchronous Tasks in Spring Boot with ThreadPoolTaskExecutor
This article explains how to configure Spring Boot's built‑in ThreadPoolTaskExecutor, customize its core parameters, and use it together with Java 8 CompletableFuture to run asynchronous tasks, including a performance comparison with a synchronous implementation.
Scenario
When building a Spring Boot application you often need a thread pool for asynchronous processing. The article first reviews the general use of Java's ExecutorService (both Runnable and Callable) and points to external blogs for deeper background. Spring provides its own wrapper, ThreadPoolTaskExecutor, which is a Spring‑managed version of JDK's ThreadPoolExecutor. By default Spring Boot auto‑configures a ThreadPoolTaskExecutor bean, but developers can override the default parameters.
Implementation
1. Configuration in a real project (Ruoyi)
The article uses the open‑source Ruoyi project as an example. The configuration class is placed under com.ruoyi.framework.config and defines a bean named threadPoolTaskExecutor:
package com.ruoyi.framework.config;
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
public class ThreadPoolConfig {
// core pool size
private int corePoolSize = 50;
// maximum pool size
private int maxPoolSize = 200;
// queue capacity
private int queueCapacity = 1000;
// keep‑alive seconds
private int keepAliveSeconds = 300;
@Bean(name = "threadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds);
// rejection policy when the pool is saturated
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}An image (omitted here) shows the location of the configuration file within the Ruoyi codebase.
2. Using CompletableFuture for asynchronous tasks
Java 8’s CompletableFuture can orchestrate async work. The article links to another blog that demonstrates this pattern.
3. Injecting the executor
Anywhere a thread pool is needed, the configured bean can be autowired:
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;4. Performance test with a unit test
A JUnit test measures the time taken when five asynchronous tasks run in parallel using the executor:
@Test
public void test2() {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
for (int i = 0; i < 5; i++) {
int finalI = i;
CompletableFuture.runAsync(() -> {
System.out.println(finalI + " executing async operation…");
int result = 0;
for (int j = 0; j < 1_000_000; j++) {
result += j;
}
System.out.println("Result:" + result);
}, threadPoolTaskExecutor);
}
stopWatch.stop();
System.out.println("Total time:" + stopWatch.getLastTaskTimeMillis());
}The resulting console output (shown in an image) displays the total execution time.
5. Comparison with a synchronous loop
A second test runs the same computation sequentially without async:
@Test
public void test1() {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
for (int i = 0; i < 5; i++) {
int result = 0;
for (int j = 0; j < 1_000_000; j++) {
result += j;
}
System.out.println("Result:" + result);
}
stopWatch.stop();
System.out.println("Total time:" + stopWatch.getLastTaskTimeMillis());
}An accompanying image shows the longer total time for the synchronous version, illustrating the performance benefit of using ThreadPoolTaskExecutor with CompletableFuture.
Through these steps the article demonstrates how to configure, inject, and employ Spring’s thread pool for real‑world asynchronous workloads, and provides concrete timing evidence of the speedup achieved.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
The Dominant Programmer
Resources and tutorials for programmers' advanced learning journey. Advanced tracks in Java, Python, and C#. Blog: https://blog.csdn.net/badao_liumang_qizhi
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
