如果没有额外引用jar包,spring项目中使用线程池一般有两种方法;
ThreadPoolExecutor
private static final ThreadPoolExecutor threadPoolExecutor =
new ThreadPoolExecutor(2,4,0,
TimeUnit.MINUTES,new LinkedBlockingQueue<>());
threadPoolExecutor.execute(()->{});
这种方式下,线程池没有交给spring管理,队列及在执行中的任务会直接丢弃;
需要手动在PreDestory中进行处理;
public void preDestroy() throws InterruptedException {
log.info("preDestroy");
log.info("线程池中队列数量:"+threadPoolExecutor.getQueue().size());
threadPoolExecutor.shutdown(); // 拒绝新任务加入
// 立即关闭线程池 返回false
// threadPoolExecutor.shutdownNow(); // 会中断
// 超时未完成 返回false
if(threadPoolExecutor.awaitTermination(10L,TimeUnit.SECONDS)){
log.info("关闭");
log.info("线程池中线程数量:"+threadPoolExecutor.getQueue().size());
}else{
log.info("未安全关闭");
log.info("线程池中线程数量:"+threadPoolExecutor.getQueue().size());
}
}
- shutdown:
不再接收新的任务,等待已提交任务执行完成, 通过以下几个步骤完成- 设置线程池状态为shutdown, 而非runing状态下 addWoker都是返回的false, 会进入 rejectedExecution
- 调用 interruptIdleWorkers 释放空闲线程 获得任务的线程会拿到锁,所以在tryLock中是失败的 这里不会中断执行中的任务
- 设置线程池状态为shutdown, 而非runing状态下 addWoker都是返回的false, 会进入 rejectedExecution
- shutdownNow:尝试停止所有正常执行的任务,并返回等待执行的队列列表, 通过以下几个步骤完成
- 设置状态为stop , 同shutdown,stop状态也是拒绝新增任务,同时runWorker中新拿到的任务也是会进行中断 尝试停止任务
- 调用interruptWorkers 对所有任务进行中断 尝试停止
- awaitTermination: 等待线程池关闭
spring @Async方式
这类线程池继承了ExecutorConfigurationSupport
默认调用shutdownNow 并调用remainingTask.cancal