如何优雅终止线程/线程池
如何优雅终止线程
分为两个阶段终止线程
1、interrupted()
: 让线程从休眠状态转换到RUNNABLE 状态
2、线程终止的标志位
:线程会在合适的时机检查这个标志位,如果发现符合终止条件,则自动退出 run() 方法
public class MonitorThread extends Thread {//在监控线程中添加一个volatile类型的标志变量,用于标识是否需要终止线程的执行private volatile boolean terminated = false;public void run() {while (!terminated) {// 执行监控操作System.out.println("监控线程正在执行监控操作...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}// 执行清理操作System.out.println("监控线程正在执行清理操作...");releaseResources();}public void terminate() {//设置标志变量为true,并等待一段时间terminated = true;try {join(5000); // 等待5秒钟,期间监控线程会检查terminated的状态} catch (InterruptedException e) {e.printStackTrace();}}private void releaseResources() {// 释放资源和进行必要的清理工作System.out.println("监控线程正在释放资源和进行必要的清理工作...");}public static void main(String[] args) throws InterruptedException {MonitorThread thread = new MonitorThread();//启动监控线程thread.start();//主线程休眠期间,监控线程在执行监控操作Thread.sleep(10000);//终止监控线程thread.terminate();Thread.sleep(100000);}
}
如何优雅终止线程池
线程池有两个终止线程池API:shutdownNow()、shotdown()
1、shotdown
:会停止线程池接受新的任务,并等待线程池中的所有任务执行完毕
,然后关闭线程池。。在调用shutdown()方法后,线程池不再接受新的任务,但是会将任务队列中的任务继续执行直到队列为空。如果线程池中的任务正在执行,但是还没有执行完毕,线程池会等待所有任务执行完毕后再关闭线程池。
2、shutdownNow
:会停止线程池接受新的任务,并尝试中断正在执行任务的线程,然后关闭线程池。在调用shutdownNow()方法后,线程池不再接受新的任务,同时会中断正在执行任务的线程并返回一个未执行的任务列表
3、awaitTerminal
等待线程池中的任务执行完毕,或者超时时间到达
public static void main(String[] args) throws InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(5);for (int i = 0; i < 10; i++) {executorService.submit(() -> {try {// 执行任务操作System.out.println(Thread.currentThread().getName() + "正在执行任务...");Thread.sleep(5000);} catch (InterruptedException e) {// 重新设置中断状态Thread.currentThread().interrupt();e.printStackTrace();} finally {System.out.println(Thread.currentThread().getName() + "任务执行完毕");}});}// 停止线程池接受新的任务,但不能强制停止已经提交的任务executorService.shutdown();// 等待线程池中的任务执行完毕,或者超时时间到达boolean terminated = executorService.awaitTermination(3, TimeUnit.SECONDS);if (!terminated) {// 如果线程池中还有未执行完毕的任务,则调用线程池的shutdownNow方法,中断所有正在执行的任务// 如果有还没开始执行的任务,则返回未执行的任务列表List<Runnable> tasks = executorService.shutdownNow();System.out.println("剩余未执行的任务数:" + tasks.size());}}