多线程(一) -- java线程(四) -- interrupt方法详解

32 篇文章 7 订阅
订阅专栏

1. interrupt打断线程

1.1 打断sleep,wait,join(阻塞状态)的线程

public static void main(String[] args) throws InterruptedException{
    Thread t1 = new Thread(() -> {
       log.debug("sleep;;;");
        try {
            Thread.sleep(5000); // sleep,join,wait
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }, "t1");
    t1.start();
    Thread.sleep(1000);
    log.debug("interrupt");
    t1.interrupt();
    log.debug("打断标记:{}", t1.isInterrupted());
}

结果:

22:01:29.967 [t1] DEBUG com.multiThread.TestInterrupt1 - sleep;;;
22:01:30.963 [main] DEBUG com.multiThread.TestInterrupt1 - interrupt
22:01:30.963 [main] DEBUG com.multiThread.TestInterrupt1 - 打断标记:false
java.lang.InterruptedException: sleep interrupted
	at java.base/java.lang.Thread.sleep(Native Method)
	at com.yhx.toali.multiThread.TestInterrupt1.lambda$main$0(TestInterrupt1.java:16)
	at java.base/java.lang.Thread.run(Thread.java:830)

可以看出阻塞状态的线程,被打断后会抛出一个异常;同时阻塞状态的线程被打断后,会将打断标记置为假

1.2 打断正常执行的线程

给定一个死循环,如何打断这个死循环:

public static void main(String[] args) throws InterruptedException{
    Thread t1 = new Thread(() -> {
       while (true) {

       }
    }, "t1");
    t1.start();
    Thread.sleep(1000);
    log.debug("interrupt");
    t1.interrupt();
}

执行结果:可以看到程序并没有停止,还在一直执行
在这里插入图片描述
我们可以通过获取打断状态来停止这个线程:

public static void main(String[] args) throws InterruptedException{
    Thread t1 = new Thread(() -> {
       while (true) {
            if (Thread.currentThread().isInterrupted()) {
                log.debug("被打断,退出");
                break;
            }
       }
    }, "t1");
    t1.start();
    Thread.sleep(1000);
    log.debug("interrupt");
    t1.interrupt();
}

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

2. 两阶段终止模式

在一个线程t1中如何“优雅”地终止线程t2?这里的“优雅”指的是给t2一个料理后事的机会。

2.1 错误思路:

  • 使用线程对象的stop()方法停止线程
    • stop方法会真正杀死线程,如果这时线程锁住了共享资源,那么当它被杀死后就再也没有机会释放锁,其他线程将永远无法获取锁
  • 使用System.exit(int)方法停止线程
    • 目的仅是停止一个线程,但是这种做法会让整个程序都停止

2.2 实现思路:

在这里插入图片描述

2.3 代码展示:

public class TestInterrupt3 {
    public static void main(String[] args) throws InterruptedException{
        TwoPhaseTermination twoPhaseTermination = new TwoPhaseTermination();
        twoPhaseTermination.start();

        Thread.sleep(3500);
        twoPhaseTermination.stop();
    }
}

@Slf4j
class TwoPhaseTermination {
    private Thread monitor;

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

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

执行结果:

22:44:24.932 [Thread-0] DEBUG com.yhx.toali.multiThread.TwoPhaseTermination - 执行监控记录
22:44:25.947 [Thread-0] DEBUG com.yhx.toali.multiThread.TwoPhaseTermination - 执行监控记录
22:44:26.948 [Thread-0] DEBUG com.yhx.toali.multiThread.TwoPhaseTermination - 执行监控记录
java.lang.InterruptedException: sleep interrupted
	at java.base/java.lang.Thread.sleep(Native Method)
	at com.yhx.toali.multiThread.TwoPhaseTermination.lambda$start$0(TestInterrupt3.java:36)
	at java.base/java.lang.Thread.run(Thread.java:830)
22:44:27.432 [Thread-0] DEBUG com.yhx.toali.multiThread.TwoPhaseTermination - 料理后事

如果注释掉catch中的interrupt,查看执行结果:可以看到执行没有停止,这是因为:当线程在执行阻塞操作时(比如调用sleep/wait/yield/join方法时)调用了interrupt()会抛出InterruptException异常并且将该线程的”中断”标志位清空,会将线程的中断标志重新设置为false。所以在需要在线程是打断状态下重新调用interrupt方法,将线程状态设置为打断,触发料理后事方法。
在这里插入图片描述

3. interrupted()和isInterrupted()区别:

3.1 修改上述料理后事的代码:

if (current.isInterrupted()) {
    log.debug("料理后事");
    System.out.println(current.isInterrupted());
    break;
}

结果:

11:52:43.814 [Thread-0] DEBUG com.yhx.toali.multiThread.TwoPhaseTermination - 执行监控记录
11:52:44.823 [Thread-0] DEBUG com.yhx.toali.multiThread.TwoPhaseTermination - 执行监控记录
11:52:45.831 [Thread-0] DEBUG com.yhx.toali.multiThread.TwoPhaseTermination - 执行监控记录
java.lang.InterruptedException: sleep interrupted
	at java.base/java.lang.Thread.sleep(Native Method)
	at com.yhx.toali.multiThread.TwoPhaseTermination.lambda$start$0(TestInterrupt3.java:42)
	at java.base/java.lang.Thread.run(Thread.java:830)
11:52:46.316 [Thread-0] DEBUG com.yhx.toali.multiThread.TwoPhaseTermination - 料理后事
true

3.2 修改上述current.isInterrupted()monitor.interrupted()

if (monitor.interrupted()) {
    log.debug("料理后事");
    System.out.println(current.isInterrupted());
    break;
}

结果:

11:54:41.316 [Thread-0] DEBUG com.yhx.toali.multiThread.TwoPhaseTermination - 执行监控记录
11:54:42.349 [Thread-0] DEBUG com.yhx.toali.multiThread.TwoPhaseTermination - 执行监控记录
11:54:43.356 [Thread-0] DEBUG com.yhx.toali.multiThread.TwoPhaseTermination - 执行监控记录
java.lang.InterruptedException: sleep interrupted
	at java.base/java.lang.Thread.sleep(Native Method)
	at com.yhx.toali.multiThread.TwoPhaseTermination.lambda$start$0(TestInterrupt3.java:42)
	at java.base/java.lang.Thread.run(Thread.java:830)
11:54:43.793 [Thread-0] DEBUG com.yhx.toali.multiThread.TwoPhaseTermination - 料理后事
false

3.3 结论:

  1. 他们都是获取打断线程状态,但是isInterrupted不会清除打断标记,而interrupted会
    也就是说调用interrupted方法会返回当前线程中断状态,同时清除中断状态(置为false)
  2. Thread.interrupted() 线程静态方法,
    Thread.currentThread().isInterrupted() 线程实例方法

3.4 源码查看:

interrupted:

public static boolean interrupted() {
    Thread t = currentThread();
    boolean interrupted = t.interrupted;
    // We may have been interrupted the moment after we read the field,
    // so only clear the field if we saw that it was set and will return
    // true; otherwise we could lose an interrupt.
    if (interrupted) {
        t.interrupted = false;
        clearInterruptEvent();
    }
    return interrupted;
}

isInterrupted:

public boolean isInterrupted() {
    return interrupted;
}

可以看到他们拿到的都是Thread的成员变量interrupted的值,不过interrupted拿到之后还会设置其为fasle

private volatile boolean interrupted;
JAVA线程 -- Interrupt
weixin_44489428的博客
03-24 1705
java线程interrupt
并发编程之interrupt方法的详细解析
qq_69748833的博客
03-17 550
stop 方法会真正杀死线程,如果这时线程锁住了共享资源,那么当它被杀死后就再也没有机会释放锁, 其它线程将永远无法获取锁。的本质是将线程的打断标记设为true,并调用线程的三个parker对象(C++实现级别)unpark该线程。打断正在运行中的线程并不会影响线程的运行,但如果线程监测到了打断标记为true,可以自行决定后续处理。interrupt 可以打断正在执行的线程,无论这个线程是在 sleep,wait,还是正常运行。打断 sleep 的线程, 会清空打断状态,以 sleep 为例。
多线程 interrupt()方法
dimei8552的博客
01-01 148
java interrupt()方法只是设置线程的中断标记,当对处于阻塞状态的线程调用interrupt方法时(处于阻塞状态的线程是调用sleep, wait, join 的线程),会抛出InterruptException异常,而这个异常会清除中断标记。并且异常如果被捕获且没有重新抛出后续代码将继续执行。Thread.interrupt()方法不会中断一个正在运行的线程。这一方法实际上...
JAVA线程interrupt
热门推荐
Robin Hu的专栏
11-11 1万+
interrupt()只是改变中断状态而已. interrupt()不会中断一个正在运行的线程。这一方法实际上完成的是,给受阻塞的线程抛出一个中断信号,     这样受阻线程就得以退出阻塞的状态。更确切 的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,    那么,它将接收到一个中断异常(InterruptedException),从而
Java多线程-线程中断interrupt
dubismile的博客
07-15 662
目录前言示例说明注意事项案例1Object#wait 和 Thread.sleep 差异在哪里总结 前言 这里主要探讨中断常用的三个方法: interrupt()。在一个线程中调用需要中断现成的interrupt()方法,会对该线程发出信号,将中断状态标志为true isInterrupted()。判断当前线程的中断状态。 interrupted()。将线程的中断状态恢复。 主要使用的阻塞三个方法: Object#wait。放弃锁+等待+重新获取锁 Thread#join。【协作】等待某个线程执行完
Java】彻底理清Java多线程开发中的中断(interrupt)方法
JeredYe的博客
12-19 4900
Java】彻底理清Java多线程开发中的中断(interrupt)方法
Java多线程之中断线程(Interrupt)的使用详解
09-05
Java中的多线程允许并发执行多个任务,而中断机制是Java提供的一种优雅地停止线程执行的方式。`Thread.interrupt()`方法是中断线程的主要手段,但它的行为并不像字面意义上那样直接终止线程。相反,它通过设置线程的...
Java多线程详解及示例
07-20
Java多线程编程是提升程序性能和响应性的关键技术。理解多线程的概念,掌握线程的创建、同步、通信、死锁避免等核心知识点,以及合理使用线程池,对于编写高效、稳定的并发程序至关重要。通过实践,开发者可以更好地...
Java 多线程与并发-Java并发知识体系详解.pdf
07-11
总的来说,Java并发编程是一个复杂但重要的主题,需要深入理解线程基础、同步机制、并发工具类等知识,才能编写出高效、稳定的多线程程序。在实际开发中,应根据具体场景选择合适的并发控制手段,合理利用Java提供的...
java多线程Thread的实现方法代码详解
08-28
现代的多线程编程中,通常使用标志变量或`interrupt()`方法来优雅地停止线程。 4. **interrupt()** `interrupt()`方法用于中断线程。当调用一个线程的`interrupt()`方法时,会设置线程的中断标志位。线程在执行...
java多线程之停止线程方法实例代码详解
08-26
总结以上所述,Java多线程之停止线程方法实例代码详解可以使用退出标记、interrupt()方法interrupted()方法来停止线程。使用退出标记停止线程简单易行,但需要对线程的执行过程进行控制。使用interrupt()方法和...
java多线程interrupt
几钱清风
08-21 404
使用 interrupt()中断线程 interrupt()本身不会真正中断一个线程,调用interrupt之后线程也是在运行状态,只是对会抛出InterruptException异常的方法进行调用时,可以捕捉到这个异常,然后如果需要线程退出,在catch中return线程就退出了 当一个线程运行时,另一个线程可以调用对应的 Thread 对象的 interrupt()方法来中断它,该方法
多线程interrupt
diaopingzhu2576的博客
11-28 461
interrupt 三兄弟 interrupt 设置中断标志位,打不打断,看线程自己安排 [当程序处于sleep,wait,join状态时打断线程,会抛出InterruptedException并重置标志位] isInterrupted 查询某线程是否被打断过 (查询标志位) interrupted 查询当前线程是否被打断过,重置标志位 案例证明:(同时interrupt 也能优雅的结束线程) public class InterruptIsWho { public static void main(Str
多线程interrupt
不废话快上车
10-15 235
interrupt多线程中 可以中断 wait() sleep() 这些等待效果 跑出一个异常 可以interrupt + 一个中断程序的标志 来结束进程 class Demo implements Runnable { boolean flag=true; public synchronized void run() { while
Java多线程interrupt()和终止线程的方式
Ybulingbuling的博客
08-05 400
一、interrupt() 说明 interrupt()的作用是中断本线程。 本线程中断自己是被允许的;其它线程调用本线程interrupt()方法时,会通过checkAccess()检查权限。这有可能抛出SecurityException异常。 如果本线程是处于阻塞状态:调用线程的wait(), wait(long)或wait(long, int)会让它进入等待(阻塞)状态,或者调用线程的j...
java 线程interrupt_Javainterrupt的使用
weixin_42514890的博客
02-12 213
通常我们会有这样的需求,即停止一个线程。在java的api中有stop、suspend等方法可以达到目的,但由于这些方法在使用上存在不安全性,会带来不好的副作用,不建议被使用。具体原因可以参考Why isThread.stopdeprecated。在本文中,将讨论中断在java中的使用。中断在java中主要有3个方法interrupt(),isInterrupted()和interrupte...
多线程 interrupt用法
私欲日生,如地上尘,一日不扫,便又有一层。着实用功,便见道无终穷,愈探愈深,必使精白无一毫不彻方可。
06-20 215
本文涉及到的两个知识点示例代码 当线程睡眠完成后 Thread.sleep(100), 开始了interrupt打断线程, 随即在循环中执行方法isInterrupted(), 返回结果为true, 代表了该线程已经被打断了
java线程interrupt
最新发布
qq_40902295的博客
04-11 935
这样,被中断的线程可以在捕获异常后检查中断状态,并据此进行清理工作或退出循环。因此,如果线程在等待锁的过程中被中断,它将继续等待,直到它最终能够获取到锁。例如,一个监听用户输入的线程在接收到特定的中断信号时,可能会调用自身的。被中断的线程不会立即停止执行,而是会在检查中断状态后决定是否响应中断。方法本身不会清除中断状态,所以在唤醒后,如果需要的话,你可能需要手动清除中断状态,通过再次调用。调用响应中断,在Java中,线程的中断是一种协作机制,线程需要自行检查中断状态并响应。如果线程在等待锁的过程中被中断,
多线程中的interrupt()方法介绍
weixin_34250434的博客
03-25 412
作用 用来中断阻塞任务,如果任务没有阻塞就不会抛出中断异常。 方法 Thread类的interrupt()设置线程中断状态为true。 调用Executor的shutdownNow()方法。 调用**Future<?>**的cancel(true)方法。 何时触发 当任务要进入到阻塞操作或处于阻塞操作内部时,就会发生中断,即InterruptException异常。 例外 I/O操...
Java多线程线程调度详解-Sun SL-275教程
"本资源是关于Sun公司的认证课程JAVASL-275中的Java编程教程,涵盖了从基础语法到高级特性的讲解,包括多线程、I/O流和网络编程等内容。" 在Java编程中,线程调度是多线程编程的重要组成部分。线程的调度指的是操作...
写文章

热门文章

  • 达梦数据库使用配置及问题整理 14253
  • break和continue跳出多重循环 11816
  • WebSocket(一) -- 原理详解 10729
  • Mysql学习(十)-- Mysql子查询关键字的使用(in和exists) 10375
  • JVM问题(一) -- 如何打破双亲委派模型 5199

分类专栏

  • 面试知识点整理 15篇
  • 数据结构 31篇
  • SpringCloud 15篇
  • 多线程 32篇
  • mysql 25篇
  • rabbitmq 7篇
  • Redis 22篇
  • Java集合框架 10篇
  • nginx 3篇
  • 分布式架构 1篇
  • java虚拟机 29篇
  • Linux 10篇
  • java基础 17篇
  • docker 11篇
  • shiro 3篇
  • 其他数据库 1篇
  • maven 2篇
  • 网络 4篇
  • lucene 1篇
  • 项目 1篇
  • quartz + batch 8篇
  • 大数据 -- kylin 4篇
  • git 1篇
  • 设计模式 8篇
  • Spring 4篇
  • js问题 4篇
  • IDEA使用 1篇
  • tomcat 3篇
  • springboot 3篇
  • 自然语言处理 1篇
  • leetcode 14篇
  • JDK常用类 3篇

最新评论

  • 数据结构(十六) -- 树(八) --2-3-4树

    m0_74009047: 2-3-4的普通删除那有一点我看不懂,如果所谓当前节点的兄弟节点不是二叉节点但有子结点,你把他的数据借给了当前节点,那他自己多的那一个孩子该怎么办呢

  • Spring源码解析 -- Spring bean的生命周期在何时完成依赖注入

    syhleo: 引用「g在Bean的生命周期中,会调用BeanPostProcessor这个后置处理器,内部就是用策略模式」 这个实现并不是策略模式,spring底层在bean的生命周期中,是会for循环调用这些扩展点的。如果你理解为策略模式,相当于每一次都会把所有的策略执行一次。

  • 原码、反码和补码介绍及为什么用补码计算

    做而论道_CS: 计算机中,使用二进制,是没错的。 但是,数值、代码,是有区别的。 虽然,它们都是二进制。 但是,数值和代码,并不是相等的关系。 比如,你的学号,你的电话号码,能相等吗? 许多计算机专家,都是稀里糊涂的乱讲!

  • 原码、反码和补码介绍及为什么用补码计算

    做而论道_CS: 另外,你写的: [-1] = [10000001]原 = [11111110]反 = [11111111]补 这写法,也是错误的。 它们之间,不是相等的,不能用等号(=)连在一起。 应该分开写:  [-1]原 = 1000 0001;  [-1]反 = 1111 1110;  [-1]补 = 1111 1111。 当然,这肯定不是你的错。 很多计算机教材的作者,基本概念都不清。 写的书,都是错误百出的。

  • 原码、反码和补码介绍及为什么用补码计算

    做而论道_CS: 从 “原码反码取反加一” 开始学习计算机知识,就完蛋了。 都学完了,你也理解不了:  负数,为什么要用正数(补码)代替?  正数,为什么就不用变换呢?  减法,怎么就能用加法实现? 你虽然可以背下来一些公式,能做一些加减运算, 但是,【知其然不知其所以然】! 大学,其实,就是专家卖弄垃圾的场所。 有用的东西,基本上,都没有讲。

最新文章

  • 面试知识点梳理及相关面试题(十五)-- spring
  • mysql查询字段未加引号问题及隐式转换
  • Mysql学习(十一) -- 常见问题处理
2023年22篇
2022年84篇
2021年23篇
2020年123篇
2019年40篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

玻璃钢生产厂家河北走廊商场美陈批发价四川成都玻璃钢雕塑动物玻璃钢雕塑报价多少玻璃钢雕塑模具定做厂家奥体夏季商场美陈武汉玻璃钢游乐圆雕塑不锈钢牛玻璃钢景观雕塑衡阳玻璃钢雕塑玻璃钢八骏马雕塑铸造南阳景观园林校园玻璃钢雕塑云南水果玻璃钢雕塑玻璃钢景观雕塑厂家地址嘉禾精神堡垒玻璃钢雕塑郑州景观玻璃钢卡通雕塑制作厂家河南多彩玻璃钢雕塑设计标识玻璃钢雕塑厂浙江玻璃钢人物雕塑商家玻璃钢花盆被热捧公园景观玻璃钢雕塑生产扬州设计玻璃钢雕塑报价盘龙区玻璃钢雕塑造型厂家服装商场美陈图片大全玻璃钢孔子雕塑哪个品牌好黄石港玻璃钢雕塑厂家好的宁夏玻璃钢雕塑澳门玻璃钢动物牛雕塑扬州仿石材玻璃钢花盆玻璃钢雕塑英语河源玻璃钢抽象人物雕塑周年庆典商场美陈批发香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化