目录
- 一、怎么优雅地关闭一个线程?
 - 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信号,继续运行线程。
	声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
		
评论(0)