1.配置异步线程池参数
#核心线程数
spring.task.pool.corePoolSize=100
#最大线程数
spring.task.pool.maxPoolSize=200
#设置线程活跃时间(秒)
spring.task.pool.keepAliveSeconds=30
#配置队列大小
spring.task.pool.queueCapacity=200
2.获取配置
@Configuration
@ConfigurationProperties(prefix = "spring.task.pool")
public class TaskThreadPoolConfig {
private int corePoolSize;
private int maxPoolSize;
private int keepAliveSeconds;
private int queueCapacity;
public int getCorePoolSize() {
return corePoolSize;
}
public void setCorePoolSize(int corePoolSize) {
this.corePoolSize = corePoolSize;
}
public int getMaxPoolSize() {
return maxPoolSize;
}
public void setMaxPoolSize(int maxPoolSize) {
this.maxPoolSize = maxPoolSize;
}
public int getKeepAliveSeconds() {
return keepAliveSeconds;
}
public void setKeepAliveSeconds(int keepAliveSeconds) {
this.keepAliveSeconds = keepAliveSeconds;
}
public int getQueueCapacity() {
return queueCapacity;
}
public void setQueueCapacity(int queueCapacity) {
this.queueCapacity = queueCapacity;
}
}
3.初始化线程池
@Configuration
public class TaskExecutePool {
@Autowired
private TaskThreadPoolConfig taskThreadPoolConfig;
@Bean(name = "ThreadPoolTaskExecutor")
public Executor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(taskThreadPoolConfig.getCorePoolSize());
executor.setMaxPoolSize(taskThreadPoolConfig.getMaxPoolSize());
executor.setQueueCapacity(taskThreadPoolConfig.getQueueCapacity());
executor.setThreadNamePrefix("ThreadPoolTaskExecutor-");
executor.setKeepAliveSeconds(taskThreadPoolConfig.getKeepAliveSeconds());
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
4.Application 需要增加注解 @EnableAsync 和
@EnableConfigurationProperties({ TaskThreadPoolConfig.class }) // 开启配置属性支持
5.方法里面使用异步线程
@Async("ThreadPoolTaskExecutor")
public void test() {
//异步执行方法
}
6.这里针对线程池的策略做下说明。
handler : 线程池对拒绝任务的处理策略。在 ThreadPoolExecutor 里面定义了 4 种 handler 策略,分别是
1. CallerRunsPolicy :这个策略重试添加当前的任务,他会自动重复调用 execute() 方法,直到成功。
2. AbortPolicy :对拒绝任务抛弃处理,并且抛出异常。
3. DiscardPolicy :对拒绝任务直接无声抛弃,没有异常信息。
4. DiscardOldestPolicy :对拒绝任务不抛弃,而是抛弃队列里面等待最久的一个线程,然后把拒绝任务加到队列
#通过如下方式设置
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
这里考虑使用其他策略,或者使用超时时间
//用来设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
//该方法用来设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住。
taskExecutor.setAwaitTerminationSeconds(60);
使用 CallerRunsPolicy 的话,如果异步线程执行时间过长,线程无法释放,新进来的无法获取到线程,那么异步的方法会阻塞,导致接口异常。