两阶段终止
两阶段终止,即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();
}
}
命名为两阶段终止,是因为代码中设置了两次打断。要设置第二次打断的原因是阻塞状态被打断会清空打断标志,需要重新设置一次打断才能终止线程。