TaskExecutor 是什么?
Spring 的 TaskExecutor 本质上是对 Java Executor 的抽象封装,用来异步执行任务,把任务提交到线程池里运行,而不是阻塞当前线程。
主要作用:解耦任务提交与执行,提升并发能力和系统吞吐量。
常见场景:
- 异步方法执行(配合 @Async 使用)。
- 并发处理耗时任务(如批量数据处理、文件上传、消息发送)。
- 后台任务执行(日志写入、通知推送、邮件发送)。
一句话理解:TaskExecutor 就是 Spring 提供的"线程池接口",常用于异步化和并发任务处理。
Spring Boot 自动配置类
所在包:org.springframework.boot.autoconfigure.task
类名:TaskExecutionAutoConfiguration
java
@ConditionalOnClass(ThreadPoolTaskExecutor.class)
@AutoConfiguration
@EnableConfigurationProperties(TaskExecutionProperties.class)
@Import({ TaskExecutorConfigurations.ThreadPoolTaskExecutorBuilderConfiguration.class,
TaskExecutorConfigurations.SimpleAsyncTaskExecutorBuilderConfiguration.class,
TaskExecutorConfigurations.TaskExecutorConfiguration.class,
TaskExecutorConfigurations.BootstrapExecutorConfiguration.class })
public class TaskExecutionAutoConfiguration {
/**
* Bean name of the application {@link TaskExecutor}.
*/
public static final String APPLICATION_TASK_EXECUTOR_BEAN_NAME = "applicationTaskExecutor";
}
具体的自动配置类是由 TaskExecutorConfiguration 类来完成的。TaskExecutor 被自动配置后生成的 Bean 的名称是 "applicationTaskExecutor"。
通过 @EnableAsync 注解来启用 @Async 注解
注解:@EnableAsync
java
@Service
@EnableAsync
public class DemoService {
}
@EnableAsync 注解,可以在 @Component 、@Service、@Configuration 标注的类上使用。
使用自动配置的 TaskExecutor
具体的自动配置的类:org.springframework.boot.autoconfigure.task.TaskExecutorConfiguration
自动配置的 bean 代码如下:
java
@Configuration(proxyBeanMethods = false)
@Conditional(OnExecutorCondition.class)
@Import(AsyncConfigurerConfiguration.class)
static class TaskExecutorConfiguration {
@Bean(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME)
@ConditionalOnThreading(Threading.VIRTUAL)
SimpleAsyncTaskExecutor applicationTaskExecutorVirtualThreads(SimpleAsyncTaskExecutorBuilder builder) {
return builder.build();
}
@Bean(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME)
@Lazy
@ConditionalOnThreading(Threading.PLATFORM)
ThreadPoolTaskExecutor applicationTaskExecutor(ThreadPoolTaskExecutorBuilder threadPoolTaskExecutorBuilder) {
return threadPoolTaskExecutorBuilder.build();
}
}
从以上代码可以看出自动配置的Bean 的名称是 "applicationTaskExecutor", 具体类型因使用的线程类型而不同。
java
package com.example.demo.service;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
@Service
@EnableAsync
public class DemoService {
/**
* 异步执行的任务方法,无返回值
* 该方法会在后台线程中执行,模拟耗时操作(休眠10秒)
* 使用@Async注解标记为异步方法
*/
@Async
public void asyncTask() {
try {
// 模拟耗时操作,线程休眠10秒
Thread.sleep(10000);
} catch (InterruptedException e) {
// 恢复中断状态,保持线程的中断标志
Thread.currentThread().interrupt();
}
}
/**
* 异步执行的任务方法,带有返回值
* 该方法会在后台线程中执行,模拟耗时操作(休眠10秒),然后返回结果
* 使用@Async注解标记为异步方法
*
* @return Future<String> 异步执行结果的Future对象,包含返回字符串"Hello, World!"
*/
@Async
public Future<String> asyncTaskWithReturnValue() {
try {
// 模拟耗时操作,线程休眠10秒
Thread.sleep(10000);
} catch (InterruptedException e) {
// 恢复中断状态,保持线程的中断标志
Thread.currentThread().interrupt();
}
// 返回异步执行结果
return CompletableFuture.completedFuture("Hello, World!");
}
}
java
@Autowired
private TaskExecutor applicationTaskExecutor;
@RequestMapping("/task")
public Response task() {
applicationTaskExecutor.execute(() -> {
System.out.println("task execute");
});
return Response.buildSuccess();
}
@RequestMapping("/asyncTask")
public Response demo() throws ExecutionException, InterruptedException {
Future<String> stringFuture = demoService.asyncTaskWithReturnValue();
String s = stringFuture.get();
return SingleResponse.of(s);
}
使用 Spring Boot 自动配置的 TaskExecutor,通常有两种方式:
1、通过 @Autowired 注入 Bean;
2、使用 @Async 注解,注意:此注解必须用在 非 @Configuration标注的类里面的方法上。
TaskExecutor 使用的线程池默认配置
TaskExecutor 背后使用的线程池为 ThreadPoolTaskExecutor,默认参数如下:
- corePoolSize 核心线程数为 8;
- 如果指定的队列长度 > 0 则使用 LinkedBlockingQueue (有界阻塞队列),否则为 SynchronousQueue(同步队列);
- queueCapacity 队列长度默认为 Integer.MAX_VALUE,无界的;
- maxPoolSize 最大线程数默认为 Integer.MAX_VALUE;
- allowCoreThreadTimeOut 默认为 true,这意味着运行核心线程被回收;
- keepAlive 空闲时间默认为 1 分钟;
- awaitTermination ,默认 false;
- threadNamePrefix,线程名称前缀,默认 "task-"。
以上默认配置如果直接在生产上使用是有很大风险的,比如:内存溢出,部分参数默认值是不合理的,比如:queueCapacity 、maxPoolSize、allowCoreThreadTimeOut****等,可以通过 application.yml 配置文件来更改这些默认配置,比如:
XML
spring:
task:
execution:
pool:
core-size: 5 # 核心线程数
max-size: 10 # 最大线程数
queue-capacity: 100 # 队列容量
keep-alive: 60s # 非核心线程存活时间
thread-name-prefix: async-exec- # 线程名前缀
shutdown:
await-termination: true # 应用关闭时是否等待任务完成
await-termination-period: 30s # 最长等待时间
或通过实现 ThreadPoolTaskExecutorCustomizer 接口来自定义配置参数,
java
import org.springframework.boot.task.ThreadPoolTaskExecutorCustomizer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
@Component
public class TaskExecutorCustomizer implements ThreadPoolTaskExecutorCustomizer {
@Override
public void customize(ThreadPoolTaskExecutor taskExecutor) {
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(100);
taskExecutor.setKeepAliveSeconds(60);
taskExecutor.setThreadNamePrefix("async-exec-");
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
taskExecutor.setAwaitTerminationSeconds(30);
}
}
注:Spring Boot 版本为 3.5.5