场景:我们如何在t1 线程中终止t2 线程呢?

错误思路❌

  • stop():调用Thred的静态方法直接杀死线程
  • System.exit(int):除了直接杀死线程,还会直接停止掉运行线程的应用程序

为什么说这是错误的思路呢?比如t1 调用了 t2线程,此时需要终止掉t2线程,但是在t2 线程体中还有被锁住的共享资源,此时还未释放锁,如果直接调用stop()方法去终止线程,那么t1就无法得到共享资源,显然这两种方法存在一定的弊端!!

两阶段终结模式

引入两阶段终结模式,也就是为了解决上述存在的弊端。简单理解为两步:
<mark>第一阶段</mark>:打断线程运行状态
<mark>第二阶段</mark>:处理和释放其它共享资源

此终结模式并不是真正意义上面的终止,也就是不能通过调用线程的stop()方法或者System.exit(0)方法进行杀死线程。

看一个例子:
场景:我们需要在main线程中终止t1(监控)线程的运行

@Slf4j(topic = "c.Test7")
public class Test7 {
   
    //定义监控线程
    private Thread thread;

    public static void main(String[] args) throws InterruptedException {
   
        Test7 test7 = new Test7();
        //启动线程
        test7.start();
        Thread.sleep(1000);
        //终止线程
        test7.stop();
    }
    //启动监控线程
    public void start(){
   
        thread = new Thread("t1"){
   
            @Override
            public void run() {
   
                //执行监控
                while (true){
   
                    boolean interrupted = currentThread().isInterrupted();
                    //是否被打断
                    if (interrupted){
   
                        log.debug("监控系统被打断");
                        //处理阶段2的业务代码...
                        break;
                    }
                    try {
   
                        Thread.sleep(10000);
                        log.debug("执行监控记录");
                    } catch (InterruptedException e) {
   
                        e.printStackTrace();
                        thread.interrupt();      //重新将打断标志置为true
                    }

                }
            }
        };
        thread.start();

    }

    //停止监控线程
    public void stop(){
   
        thread.interrupt();
    }
}

分析:
我们知道当没有遇到堵塞状态的异常抛出时,线程被打断,打断标志会被置为true,此时正常终止,当遇到堵塞状态的异常抛出,此时打断标志会被置为false,会被异常InterruptedException 抓住来处理,要注意的是要把打断标志置为true,进入if后我们应该做的是<mark>阶段2</mark>的事情,才能正常退出线程!