1、启用异步支持
在启动类或配置类上添加@EnableAsync注解,激活异步处理能力。
java
@SpringBootApplication
@EnableAsync
public class Application {
}
2、自定义线程池
java
@Configuration
public class AsyncConfig {
@Bean("customExecutor")
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10); // 核心线程数
executor.setMaxPoolSize(20); // 最大线程数
executor.setQueueCapacity(100); // 队列容量
executor.setThreadNamePrefix("Async-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
Spring Boot 2.1.0 之前的版本默认线程池:SimpleAsyncTaskExecutor。此线程池的特点是每次执行任务时都会新建线程(不重用线程),且不限制线程数量,高并发场景下可能导致资源耗尽。
Spring Boot 2.1.0 及更高版本默认线程池:ThreadPoolTaskExecutor。Spring Boot 在 TaskExecutionAutoConfiguration 中自动配置了一个默认线程池,核心参数为:核心线程数:8,最大线程数:Integer.MAX_VALUE,队列容量:Integer.MAX_VALUE,线程名前缀:task-,此线程池的 Bean 名称为 applicationTaskExecutor,在未自定义线程池时会优先使用它。
3、定义异步方法
在需要异步执行的方法上添加@Async,并确保该方法所属类被Spring管理(如使用@Service或@Component注解),使用时指定线程池名称。
java
@Service
public class AsyncService {
@Async("customExecutor")
public void sendSms() {
// 异步执行逻辑
}
}
注意:禁止同类调用:异步方法不能在同一个类中通过内部方法调用,必须通过Spring代理对象调用(如通过@Autowired注入自身)。@Async仅对public方法生效。@Async不能修饰静态方法。异步类需避免循环依赖,否则可能导致代理失效。
任务提交阶段 | 活跃线程数 | 队列占用 | 线程池状态 | 关键现象 |
---|---|---|---|---|
初始 10 任务 | 10 | 0/100 | 核心线程饱和 | 无队列堆积 |
累计 110 任务 | 10 | 100/100 | 队列满载,线程未扩容 | 任务开始延迟 |
累计 120 任务 | 20 | 100/100 | 线程池扩容至最大值 | 系统负载达到峰值 |
累计 121 任务 | 20 | 100/100 | 触发拒绝策略 | 服务降级,需告警干预 |