龙哥网

龙哥网

java 两阶段终止线程的正确做法_java
2022-03-01

目录
  • 一、怎么优雅地关闭一个线程?
    • 1.错误做法
    • 2.正确做法
  • 二、要点

    一、怎么优雅地关闭一个线程?

    在一个线程T1中如何优雅地关闭线程T2(也就是说要给T2一个机会释放持有的资源)?

    1.错误做法

    使用stop()方法停止线程:

    stop()方法会真正杀死线程,如果此时该线程持有锁,那么其他线程将永远无法获取锁。

    使用System.exit()方法停止线程:

    会让整个进程都退出

    2.正确做法

    思路:

    代码实现:

    public class Test {
        public static void main(String[] args) throws InterruptedException {
            TwoPhaseTermination twoPhaseTermination = new TwoPhaseTermination();
            twoPhaseTermination.start();
    
            Thread.sleep(3000);
            twoPhaseTermination.stop();
    
        }
    }
    
    class TwoPhaseTermination{
        // 监控线程
        private Thread monitorThread;
    
        public void start(){
            monitorThread = new Thread(()->{
                Thread current = Thread.currentThread();
                while(true){
                    if(current.isInterrupted()){
    
                        System.out.println("线程要关闭了...");
                        break;
                    }
                    try {
                        Thread.sleep(1000); // 阶段1
                        System.out.println("监控线程正在工作...."); // 阶段2
                         // 如果在阶段2被打断,线程的isInterrupted标志位为true,会捕抓到信号并关闭线程
                         // 如果在阶段1被打断,会进入catch语句块,并且isInterrupted标志位清空,无法关闭线程
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        // 需要重新设置isInterrupted标志位为true
                        monitorThread.interrupt();
                    }
                }
    
            });
            // 启动线程
            monitorThread.start();
        }
    
        public void stop(){
            // 设置isInterrupted标志位true
            monitorThread.interrupt();
        }
    }
    
    

    运行结果:

    两阶段关闭线程:

    二、要点

    为什么需要在catch代码块中重新执行monitorThread.interrupt()?因为Thread.sleep()执行过程中被打断,isInterrupted标志位会清空,下一次进入while循环就会忽略这次打断,继续运行线程。

    演示一下把monitorThread.interrupt()注释掉的结果:

    可以看到,会忽略这次的isInterrupted信号,继续运行线程。

    免责声明
    本站部分资源来源于互联网 如有侵权 请联系站长删除
    龙哥网是优质的互联网科技创业资源_行业项目分享_网络知识引流变现方法的平台为广大网友提供学习互联网相关知识_内容变现的方法。