两阶段终止
两阶段终止,即Two Phase Termination
。是用来终止线程的套路。
它的思想是,如何在一个线程T1中优雅地终止线程T2?这里的【优雅】指的是给T2一个料理后事的机会。
错误思路:
- 使用stop方法。stop 方法会真正杀死线程,如果这时线程锁住了共享资源,那么当它被杀死后就再也没有机会释放锁,其它线程将永远无法获取锁。
- System.exit(int)方法。这个方法是为了停止整个进程,不能使用,否则Java程序会被终止。
有一个场景:一个监控线程在监控计算机中的cpu使用情况、内存占用情况等信息。它2s监控一次。现在使用者不想要监控了,按下了停止按钮,如何让该线程终止?
package org.example;import java.util.concurrent.TimeUnit;public class Main {public static void main(String[] args) throws InterruptedException {TwoPhaseTermination twoPhaseTermination = new TwoPhaseTermination();twoPhaseTermination.start();TimeUnit.SECONDS.sleep(10);twoPhaseTermination.stop();}
}class TwoPhaseTermination{private Thread monitor;//启动一个监控线程public void start(){monitor=new Thread(()->{while (true){if (monitor.isInterrupted()){System.out.println("料理后事");System.out.println("线程终止");break;}//每隔2s执行监控try {TimeUnit.SECONDS.sleep(2);System.out.println("执行监控代码");} catch (InterruptedException e) {//在阻塞状态被打断,打断标志会被清除,需要重新设置打断标志System.out.println("阻塞打断");monitor.interrupt();}}});monitor.start();}//终止一个监控线程(两阶段终止)public void stop(){monitor.interrupt();}
}
命名为两阶段终止,是因为代码中设置了两次打断。要设置第二次打断的原因是阻塞状态被打断会清空打断标志,需要重新设置一次打断才能终止线程。