Interrupt打断线程的来龙去脉(sleep、wait、join、park、两阶段终止)

 

目录

interrupt

打断阻塞

打断正常

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

错误思路

两阶段终止模式 - interrupt分析

两阶段终止模式代码实现

Interrupt打断park

 

interrupt

打断阻塞

阻塞状态:处于阻塞状态的线程,线程调度器是不会主动让此线程使用时间片的。

能够使线程进入阻塞状态的方法有 sleep wait join.

注意:

  1. 打断正在睡眠的线程后,线程的打断标记并不会置为true,而是false。
  2. 被打断的睡眠的线程并不全是直接使用cpu时间片,仍然是处于就绪状态,还是要排队滴!

打断正常

开门见山,上案例。

如图所示,我们将t1线程进行打断,运行结果为:

所以由结果可知:正常的线程在被打断时是不会停止继续占用cpu时间片的,而是改变此线程的打断标记为true。 所以打断正常线程就相当于通知该线程有人要让你停下来,而不是强制让你停下来,非常的人性化!

如果真的想要做到 interrupt即停止,那么我们的打断标记就发挥作用了。

我们知道在打断正常线程的动作中,会使打断标记置为true,所以我们可以根据该boolen类型的值来进行判断是否打断,从而来决定线程是否进行打断(手动打断)。

代码如下:

结果如下:

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

在一个线程T1中如何优雅的终止线程T2? 这里的优雅是指给T2一个料理后事的机会。

提到终止线程,那么首先想到的就是暴力停止,就像我们电脑卡死,直接关机一样。但是在线程中暴力杀死线程可是会有大麻烦的。

错误思路

  • 暴力stop()方法停止线程

stop方法会真正杀死线程,如果这时线程锁住了共享资源,那么当它被杀死后就再也没有机会释放锁,其他线程将永远无法获得锁

  • 使用System.exit(int)方法停止线程

目的是停止一个线程,但该做法却会让整个程序都停止,比stop还离谱。

所以这两种方法时一定要摒弃的。

两阶段终止模式 - interrupt分析

流程如下:

  1. while 判断该线程的打断标记是否为true,如果为true,则说明该线程需要被停止。那么就通知该线程,去料理后事吧,然后就可以结束循环了。
  2. 如果打断标记false,那么就代表在监控时刻该线程并没有被命令停止,那么就呼吸式监控(睡眠单位时间,然后再看看有没有抛出InterruptedException)。
  3. 如果没有抛出异常,就再返回我们的第一步while 循环判断;如果抛出了异常,就说明,真的给我们的线程下了死亡通牒,所以现在就需要下达死亡通知书了,把打断标记置为true,然后再进行whlie循环判断,料理后事。

两阶段终止模式代码实现

@Slf4j(topic = "c.demo4")
public class demo4 {

    public static void main(String[] args) throws InterruptedException {
        TwoPhaseTermination tpt = new TwoPhaseTermination();
        tpt.start();
        Thread.sleep(5000);
        tpt.stop();
    }
}

@Slf4j(topic = "c.TwoPhaseTermination")
class TwoPhaseTermination {

    private Thread monitor;

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

        });
        monitor.start();
    }

    public void stop() {
        monitor.interrupt();
    }

}

Interrupt打断park

park方法并不是Thread提供的方法,而是LockSupport(锁支持)类提供的方法。

当处于park状态的线程,如果被interrupt打断,会将打断标记置为true。

注意:在处于park的线程被打断后就无法再自动执行park方法。

因为该线程的打断标记已经被置为true,如果还想让改行程继续执行park方法,就需要手动重置该线程的打断标记为false。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值