【JUC并发编程】 终止模式之两阶段终止模式

【JUC并发编程】 终止模式之两阶段终止模式

1. 两阶段终止模式(Two Phase Termination)

想象一下,我们如何在线程t1中终止线程t2?我们马上就能想到使用线程对象的 stop() 方法。但是 stop() 会真正 杀死 线程,如果此线程锁住了某些共享资源,那么当杀死这个线程时,线程不会释放锁,其他线程无法获得锁,导致被锁住的共享资源就无法被别人使用了。

我们也许还会想到能不能使用 System.exit(int status) 呢?答案是不能!因为我们的目的只是停止程序中的某一个线程,而该方法会将程序中的所有线程都停止,从而退出程序。

以上提到的两种方法都无法解决我们遇到的问题,所以我们引入 两阶段终止模式


2. 案例

案例须知:

  • public void interrupt() 实例方法,方法可以通知目标线程中断,并设置目标线程的中断标志位为 true
  • public boolean isInterrupted() 实例方法,方法可以判断线程是否被中断(通过检查中断标志位),并获取中断标志位,不会清除 打断标记
  • public static boolean interrupted() Thread类的静态方法,返回当前线程的中断状态真实值(boolean类型)后会将当前线程的中断状态设为false,会清除 打断标记 。(返回当前值并清零置false)

给出以下案例,可以很好理解两阶段终止模式。

@Slf4j(topic = "c.Test13_")
public class Test13_ {
    public static void main(String[] args) throws InterruptedException {
        TwoPhaseTermination_ t = new TwoPhaseTermination_();
        t.start();
        Thread.sleep(3000);
        t.stop();
    }
}

@Slf4j(topic = "c.TwoPhaseTermination_")
class TwoPhaseTermination_ {
    //监控线程
    private Thread monitor;

    //开启线程
    public void start() {
        monitor = new Thread(() -> {
            while (true) {
                Thread current = Thread.currentThread();
                if(current.isInterrupted()){
                    log.debug("打断标记:{}",current.isInterrupted());
                    log.debug("料理后事");
                    break;
                }
                try {
                    Thread.sleep(1000);
                    log.debug("执行监控");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    current.interrupt();
                }
            }
        }, "monitor");
        monitor.start();
    }

    //终结线程
    public void stop(){
        monitor.interrupt();
    }

}

运行结果:
在这里插入图片描述

分析:

主线程创建一个监控线程 monitor 并让他运行,每隔1s monitor 线程打印一次“执行监控”。主线程方法3s后调用终结线程方法打断 monitor 线程。执行打断方法时 monitor 有两种状态。

  • ①:在执行普通代码时被打断
  • ②:在sleep时被打断

状态①时程序不会抛出异常,主程序直接将 monitor 线程打断,并“料理后事”。状态②时,monitor 线程会抛出一个 InterruptedException 异常并被自己捕获处理,在catch块中调用 interrupt() 方法,在自己的线程中将自己打断。

注:当线程处于被阻塞状态(sleep,wait,join等状态),在别的线程中调用当前线程对象的interrupt()方法,那么线程将立即退出被阻塞状态并抛出一个InterruptedException异常。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值