JAVA多线程-两阶段终止模式
终止模式之两阶段终止模式:Two Phase Termination
目标:在一个线程 T1 中如何优雅终止线程 T2?优雅指的是给 T2 一个后置处理器
错误思想:
- 使用线程对象的 stop() 方法停止线程:stop 方法会真正杀死线程,如果这时线程锁住了共享资源,当它被杀死后就再也没有机会释放锁,其它线程将永远无法获取锁
- 使用 System.exit(int) 方法停止线程:目的仅是停止一个线程,但这种做法会让整个程序都停止
两阶段终止模式图示:
打断线程可能在任何时间,所以需要考虑在任何时刻被打断的处理方法:
public class Test {
public static void main(String[] args) throws InterruptedException {
TwoPhaseTermination tpt = new TwoPhaseTermination();
tpt.start();
Thread.sleep(3500);
tpt.stop();
}
}
class TwoPhaseTermination {
private Thread monitor;
// 启动监控线程
public void start() {
monitor = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
Thread thread = Thread.currentThread();
if (thread.isInterrupted()) {//通过线程自带的是否被中断过标签
/*
*被打断后的操作,业务处理在这里处理
*/
System.out.println("后置处理");
break;
}
try {
Thread.sleep(1000); // 睡眠
System.out.println("执行监控记录"); // 在此被打断不会异常
} catch (InterruptedException e) { // 在睡眠期间被打断,进入异常处理的逻辑
e.printStackTrace();
// 重新设置打断标记,打断 sleep 会清除打断状态
thread.interrupt();
}
}
}
});
monitor.start();
}
// 停止监控线程
public void stop() {
monitor.interrupt();
}
}
两阶段终止模式其实本质上是通过try-finally对中断的二次封装。就是当希望结束一个线程或者出现异常的时候,送出一个终止请求,但是不会马上停止,做一些刷新工作。进入“终止处理中”,在该状态下,不会进行该线程日常工作任务的操作,而是进行一些终止操作。
而在while循环中让线程睡眠1秒这是不可避免的,这是为了不让cpu一直空转占用资源。
参考视频:https://www.bilibili.com/video/BV16J411h7Rd