第一章:多线程十三之线程池的关闭
2023-11-01 10:29 阿方技术圈 阅读(54) 评论(0) 收藏 举报线程池总共存在5种状态,定义在ThreadPoolExecutor类中,具体代码如下:
package java.util.concurrent;
// 省略import
public class ThreadPoolExecutor extends AbstractExecutorService {
// runState is stored in the high-order bits
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
// 省略其他
}
线程池的5种状态具体如下:
1)RUNNING:线程池创建之后的初始状态,这种状态下可以执行任务。
(2)SHUTDOWN:该状态下线程池不再接受新任务,但是会将工作队列中的任务执行完毕。
(3)STOP:该状态下线程池不再接受新任务,也不会处理工作队列中的剩余任务,并且将会中断所有工作线程。
(4)TIDYING:该状态下所有任务都已终止或者处理完成,将会执行terminated()钩子方法。
(5)TERMINATED:执行完terminated()钩子方法之后的状态。
线程池的状态转换规则为:
(1)线程池创建之后状态为RUNNING。
(2)执行线程池的shutdown()实例方法,会使线程池状态从RUNNING转变为SHUTDOWN。
(3)执行线程池的shutdownNow()实例方法,会使线程池状态从RUNNING转变为STOP。
(4)当线程池处于SHUTDOWN状态时,执行其shutdownNow()方法会将其状态转变为STOP。
(5)等待线程池的所有工作线程停止,工作队列清空之后,线程池状态会从STOP转变为TIDYING。
(6)执行完terminated()钩子方法之后,线程池状态从TIDYING转变为TERMINATED。
关闭线程池主要涉及的方法有3个:
(1)shutdown:是JUC提供的一个有序关闭线程池的方法,此方法会等待当前工作队列中的剩余任务全部执行完成之后,才会执行关闭,但是此方法被调用之后线程池的状态转为SHUTDOWN,线程池不会再接收新的任务。
(2)shutdownNow:是JUC提供的一个立即关闭线程池的方法,此方法会打断正在执行的工作线程,并且会清空当前工作队列中的剩余任务,返回的是尚未执行的任务。
(3)awaitTermination:等待线程池完成关闭。在调用线程池的shutdown()与shutdownNow()方法时,当前线程会立即返回,不会一直等待直到线程池完成关闭。如果需要等到线程池关闭完成,可以调用awaitTermination()方法。
关闭线程池的方法
package com.heima.activiti.lhf;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
public class ThreadUtil {
public static void shutdownThreadPoolGracefully(ExecutorService threadPool){
//若已经关闭则返回
if(!(threadPool instanceof ExecutorService) || threadPool.isTerminated()){
return;
}
threadPool.shutdown();//拒绝接受新任务
try {
//等待60秒,等待线程池中的任务完成执行
if(!threadPool.awaitTermination(60, TimeUnit.SECONDS)){
threadPool.shutdownNow();
if(!threadPool.awaitTermination(60, TimeUnit.SECONDS)){
System.out.print("线程池任务未正常执行结束");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
threadPool.shutdownNow();
}
if(!threadPool.isTerminated()){
for (int i = 0;i<1000;i++){
try {
if(!threadPool.awaitTermination(10, TimeUnit.SECONDS)){
break;
}
threadPool.shutdownNow();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
浙公网安备 33010602011771号