Spring为我们提供了一个线程池ThreadPoolTaskExecutor
SpringBoot-@Async异步注解
参数说明
corePoolSize: 线程池维护线程最小数量
maxPoolSize: 线程池维护线程最大数量
keepAliveSeconds: (maxPoolSize-corePoolSize)部分线程空闲最大存活时间
queueCapacity: 阻塞任务队列(任务超过corePoolSize部分就会放到queueCapacity)
AllowCoreThreadTimeOut: 设置为true的话,keepAliveSeconds参数设置的有效时间对corePoolSize线程也有效
RejectedExecutionHandler: 当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理。
拒绝策略RejectedExecutionHandler
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
线程创建流程:
- 当线程数量小于corePoolSize时,创建线程,不管线程是不是闲置的
- 当线程数量大于等于corePoolSize时,把任务放到queueCapacity队列
- 当queueCapacity满了,就创建新的线程来执行,直到线程池大小超过maxPoolSize
- 当线程数量大于等于maxPoolSize时,根据RejectedExecutionHandler设置的策略来处理新加入的任务
配置示例:
配置信息
task:
pool:
corePoolSize: 4
queueCapacity: 2
maxPoolSize: 10
keepAliveSeconds: 300
加载配置信息
@Component
@ConfigurationProperties(prefix = "task.pool")
@Data
public class TaskThreadPoolConfig {
private int corePoolSize;
private int maxPoolSize;
private int keepAliveSeconds;
private int queueCapacity;
}
装载线程池
@Configuration
@EnableAsync
public class TaskExecutePool {
@Autowired
private TaskThreadPoolConfig config;
@Bean
public Executor myTaskAsyncPool() {
System.out.println(config.toString());
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程池大小
executor.setCorePoolSize(config.getCorePoolSize());
//最大线程数
executor.setMaxPoolSize(config.getMaxPoolSize());
//队列容量
executor.setQueueCapacity(config.getQueueCapacity());
//活跃时间
executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
//线程名字前缀
executor.setThreadNamePrefix("MyExecutor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
使用
for (int i = 0; i < 20; i++) {
myTaskAsyncPool.execute(new TestRunnable());
}