尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
多线程(一) - java线程(四) - interrupt方法详解
1. interrupt打断线程1.1 打断sleepwaitjoin阻塞状态的线程publicstaticvoidmain(String[]args)throwsInterruptedException{Threadt1newThread(()-{log.debug(sleep;;;);try{Thread.sleep(5000);// sleep,join,wait}catch(InterruptedExceptione){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 - interrupt22:01:30.963[main]DEBUG com.multiThread.TestInterrupt1 - 打断标记false java.lang.InterruptedException:sleepinterrupted 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 打断正常执行的线程给定一个死循环如何打断这个死循环publicstaticvoidmain(String[]args)throwsInterruptedException{Threadt1newThread(()-{while(true){}},t1);t1.start();Thread.sleep(1000);log.debug(interrupt);t1.interrupt();}执行结果可以看到程序并没有停止还在一直执行我们可以通过获取打断状态来停止这个线程publicstaticvoidmain(String[]args)throwsInterruptedException{Threadt1newThread(()-{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 代码展示publicclassTestInterrupt3{publicstaticvoidmain(String[]args)throwsInterruptedException{TwoPhaseTerminationtwoPhaseTerminationnewTwoPhaseTermination();twoPhaseTermination.start();Thread.sleep(3500);twoPhaseTermination.stop();}}Slf4jclassTwoPhaseTermination{privateThreadmonitor;// 启动监控线程publicvoidstart(){monitornewThread(()-{while(true){ThreadcurrentThread.currentThread();if(current.isInterrupted()){// 获取终止状态log.debug(料理后事);break;}try{Thread.sleep(1000);//情况1log.debug(执行监控记录);// 情况2}catch(InterruptedExceptione){e.printStackTrace();// 重新设置打断标记current.interrupt();}}});monitor.start();}publicvoidstop(){monitor.interrupt();}}执行结果22:44:24.932[Thread-0]DEBUGcom.yhx.toali.multiThread.TwoPhaseTermination-执行监控记录22:44:25.947[Thread-0]DEBUGcom.yhx.toali.multiThread.TwoPhaseTermination-执行监控记录22:44:26.948[Thread-0]DEBUGcom.yhx.toali.multiThread.TwoPhaseTermination-执行监控记录java.lang.InterruptedException:sleep interrupted at java.base/java.lang.Thread.sleep(NativeMethod)atcom.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]DEBUGcom.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]DEBUGcom.yhx.toali.multiThread.TwoPhaseTermination-执行监控记录11:52:44.823[Thread-0]DEBUGcom.yhx.toali.multiThread.TwoPhaseTermination-执行监控记录11:52:45.831[Thread-0]DEBUGcom.yhx.toali.multiThread.TwoPhaseTermination-执行监控记录java.lang.InterruptedException:sleep interrupted at java.base/java.lang.Thread.sleep(NativeMethod)atcom.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]DEBUGcom.yhx.toali.multiThread.TwoPhaseTermination-料理后事true3.2 修改上述current.isInterrupted()为monitor.interrupted()if(monitor.interrupted()){log.debug(料理后事);System.out.println(current.isInterrupted());break;}结果11:54:41.316[Thread-0]DEBUGcom.yhx.toali.multiThread.TwoPhaseTermination-执行监控记录11:54:42.349[Thread-0]DEBUGcom.yhx.toali.multiThread.TwoPhaseTermination-执行监控记录11:54:43.356[Thread-0]DEBUGcom.yhx.toali.multiThread.TwoPhaseTermination-执行监控记录java.lang.InterruptedException:sleep interrupted at java.base/java.lang.Thread.sleep(NativeMethod)atcom.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]DEBUGcom.yhx.toali.multiThread.TwoPhaseTermination-料理后事false3.3 结论他们都是获取打断线程状态但是isInterrupted不会清除打断标记而interrupted会。也就是说调用interrupted方法会返回当前线程中断状态同时清除中断状态置为falseThread.interrupted() 线程静态方法Thread.currentThread().isInterrupted() 线程实例方法3.4 源码查看interruptedpublicstaticbooleaninterrupted(){ThreadtcurrentThread();booleaninterruptedt.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.interruptedfalse;clearInterruptEvent();}returninterrupted;}isInterruptedpublicbooleanisInterrupted(){returninterrupted;}可以看到他们拿到的都是Thread的成员变量interrupted的值不过interrupted拿到之后还会设置其为fasleprivatevolatilebooleaninterrupted;
RELATED

相关推荐

337. 打家劫舍 III(dfs)

337. 打家劫舍 III(dfs)

链接:337. 打家劫舍 III - 力扣(LeetCode) 题解: 代码: 1.打劫当前节点:root->val left和right不打劫的最大值 2.不打劫当前节点:left打劫和不打劫的最大值right打劫和不打劫的最大值 /…

📅 2026/9/9 16:26:48
基于SpringBoot的米村拌饭订餐管理系统的设计与实现(源码+lw+部署文档+讲解等)

基于SpringBoot的米村拌饭订餐管理系统的设计与实现(源码+lw+部署文档+讲解等)

联系博主 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 …

📅 2026/9/8 2:22:40
HTML-in-Canvas API:将DOM与CSS渲染为Canvas纹理的前端高性能方案

HTML-in-Canvas API:将DOM与CSS渲染为Canvas纹理的前端高性能方案

这次我们来看一个能改变前端 UI 开发范式的技术:HTML-in-Canvas API。它不是一个新的 UI 框架,而是一个强大的浏览器原生 API,允许开发者将完整的 HTML/CSS 内容直接渲染到 Canvas 画布上。这意味着,你可以用你熟悉的 DOM 和 CSS …

📅 2026/10/18 19:49:28
MORE NEWS

更多资讯

📰

RRF 融合后还要不要重排:先画候选召回上限

RRF 能把不同检索通道的排名合到一起,但它不能把没召回的文档变出来。重排器也是一样。很多“换了重排模型还是答错”的问题,实际发生在候选池形成之前。 10 月 8 日,Qdrant 与 Pento 发布了 miniCOIL EN-ES 的双语稀疏检索研究预览&#xf…

📰

199_负载突变下转速环积分饱和的恢复过程设计

从一个反复烧驱动模块的现场说起 几年前做过一台大惯量旋转台的项目,电机通过减速机构拖动一个偏心负载。空载调试一切正常,转速环响应干脆利落。但是一旦把真实负载挂上去,做突加突卸测试,问题就来了:每次负载突然卸掉的瞬间,转速会猛地冲上去,超调大得吓人,紧接着驱…

📰

198_弱磁区电压裕量不足时的电流分配策略调整

一个把母线电压吃干榨净的现场 早年间做一套宽调速范围的永磁同步驱动项目,样机在额定转速以下跑得四平八稳,温升、噪声、效率都在预期内。问题出在往高速推的阶段:转速刚越过基速不久,控制器就开始报母线电压利用率异常,同时相电流波形上出现明显的削顶畸变,转矩输出像…

📰

197_电流环与速度环带宽配比失当引起的振荡现象

前年冬天,有个做卷绕设备的项目找到我。他们的机器在低速运行时一切正常,但产线速度提上去之后,张力就开始周期性波动,幅度越来越大,最后设备自己保护停机。现场工程师换了张力传感器、检查了机械传动、甚至把电机都拆下来重新对中,折腾了快两周,问题依旧。 我到现场之…

📰

196_反电动势谐波对转子位置估算误差的耦合分析

从一次诡异的低速抖动说起 去年冬天调一台无位置传感器永磁同步驱动样机,额定转速三千转,带载运行在中高速区间一切正常。但客户要求必须能稳定运行在百分之五额定转速以下,问题就来了。低速轻载时电机发出周期性的“咯噔咯噔”抖动,电流波形上叠加了明显的六次谐波纹波,…

📰

Agent多Agent框架实战:Router路由器与四种多智能体架构区别说明(TaoToken统一API接入)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬