# 1.什么是俩阶段终止模式:

  • 在一个线程T1中如何优雅终止线程T2,优雅就是代表终止T2的时候可以让它把被打断后想执行的逻辑执行完

# 2.应用场景

  • 例如我们想监控一台电脑的健康状态,例如cpu使用率,内存使用率等等。这种情况我们可以使用一个while(true)循环让它不断运行,可以在循环内设置每隔一段时间查看一下状态。但我们还需要一个停止按钮,当我们不想监控的时候可以正常的停止,这种情况我们可以使用俩阶段终止模式进行实现。

# 3.图例

  • 这个图还是很好理解的

image.png

  1. 代码示例
public class Test03 {
    public static void main(String[] args) throws InterruptedException {
        TwoPhaseTermination termination=new TwoPhaseTermination();
        termination.start();
        //休眠5秒后打断
        Thread.sleep(5000);
        termination.stop();
    }
}
@Slf4j(topic = "c")
class TwoPhaseTermination{
    private Thread monitor;

    public void start(){
        monitor=new Thread(()->{
            while (true){
                Thread current = Thread.currentThread();
                if (current.isInterrupted()){
                    log.info("线程被打断了,开始处理打断流程");
                    break;
                }
                try {
                    //此处休眠是表示我们每格一秒监控一下线程
                    Thread.sleep(1000);
                    log.info("监控线程");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    //将打断标记致为true
                    current.interrupt();
                }
            }

        });
        monitor.start();
    }
    public void stop(){
        monitor.interrupt();
    }
}
  • 执行结果 image.png
  • 当我们启动监控5秒后,准备停止监控,这时候会有俩种情况,第一种线程不在睡眠过程中,在监控线程,这个时候当调用interrupt()方法之后,线程的打断标记就致为ture了 下一次while循环之后就会进入到if判断里,然后这个时候我们可以在里面写一些被打断之后的逻辑,例如释放资源啥的。第二种情况,当线程处于睡眠状态,也就是Thread.sleep(1000);还没有结束,这个时候调用interrupt()方法,就会抛出异常,进入到catch块当中,同时打断标记就变为false(如果不知道为啥可以看下我上篇文章,或者百度一下); 这个时候如果我们捕获异常不进行任何处理的话,就不会进入if判断里,线程还是继续执行,所以这个时候可以在执行一次interrupt()重新将打断标记致为true,下次while循环时就能正常退出了。