摘要:我们就以一个案例的形式,来为大家详细介绍下为何中断执行的线程不起作用。

本文分享自华为云社区《明明中断了线程,却为何不起作用呢?》,作者:冰 河。

当我们在调用Java对象的wait()方法或者线程的sleep()方法时,需要捕获并处理Interrupted Exception异常。如果我们对Interrupted Exception异常处理不当,则会发生我们意想不到的后果!今天,我们就以一个案例的形式,来为大家详细介绍下为何中断执行的线程不起作用。

程序案例

例如,下面的程序代码,InterruptedTask类实现了Runnable接口,在run()方法中,获取当前线程的句柄,并在while(true)循环中,通过isInterrupted()方法来检测当前线程是否被中断,如果当前线程被中断就退出while(true)循环,同时,在while(true)循环中,还有一行Thread.sleep(100)代码,并捕获了Interrupted Exception异常。整个代码如下所示。

package io.binghe.concurrent.lab08;/*** @author binghe* @version 1.0.0* @description 线程测试中断*/
public class InterruptedTask implements Runnable{@Overridepublic void run() {Thread currentThread = Thread.currentThread();while (true){if(currentThread.isInterrupted()){break;}try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}
}

上述代码的本意是通过isInterrupted()方法检查线程是否被中断了,如果中断了就退出while循环。其他线程通过调用执行线程的interrupt()方法来中断执行线程,此时会设置执行线程的中断标志位,从而使currentThread.isInterrupted()返回true,这样就能够退出while循环。

这看上去没啥问题啊!但真的是这样吗?我们创建一个Interrupted Test类用于测试,代码如下所示。

package io.binghe.concurrent.lab08;/*** @author binghe* @version 1.0.0* @description 测试线程中断*/
public class InterruptedTest {public static void main(String[] args){InterruptedTask interruptedTask = new InterruptedTask();Thread interruptedThread = new Thread(interruptedTask);interruptedThread.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}interruptedThread.interrupt();}
}

我们运行main方法,如下所示。

这竟然跟我们想象的不一样!不一样!不一样!这是为什么呢?

问题分析

上述代码明明调用了线程的interrupt()方法来中断线程,但是却并没有起到啥作用。原因是线程的run()方法在执行的时候,大部分时间都是阻塞在sleep(100)上,当其他线程通过调用执行线程的interrupt()方法来中断执行线程时,大概率的会触发InterruptedException异常,在触发InterruptedException异常的同时,JVM会同时把线程的中断标志位清除,所以,这个时候在run()方法中判断的currentThread.isInterrupted()会返回false,也就不会退出当前while循环了。

既然问题分析清除了,那如何中断线程并退出程序呢?

问题解决

正确的处理方式应该是在InterruptedTask类中的run()方法中的while(true)循环中捕获异常之后重新设置中断标志位,所以,正确的InterruptedTask类的代码如下所示。

package io.binghe.concurrent.lab08;/*** @author binghe* @version 1.0.0* @description 中断线程测试*/
public class InterruptedTask implements Runnable{@Overridepublic void run() {Thread currentThread = Thread.currentThread();while (true){if(currentThread.isInterrupted()){break;}try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();currentThread.interrupt();}}}
}

可以看到,我们在捕获InterruptedException异常的catch代码块中新增了一行代码。

currentThread.interrupt();

这就使得我们捕获到InterruptedException异常后,能够重新设置线程的中断标志位,从而中断当前执行的线程。

我们再次运行InterruptedTest类的main方法,如下所示。

总结

处理InterruptedException异常时要小心,如果在调用执行线程的interrupt()方法中断执行线程时,抛出了InterruptedException异常,则在触发InterruptedException异常的同时,JVM会同时把执行线程的中断标志位清除,此时调用执行线程的isInterrupted()方法时,会返回false。此时,正确的处理方式是在执行线程的run()方法中捕获到InterruptedException异常,并重新设置中断标志位(也就是在捕获InterruptedException异常的catch代码块中,重新调用当前线程的interrupt()方法)。

点击关注,第一时间了解华为云新鲜技术~

为何我中断执行的线程不起作用,Why相关推荐

  1. while(true) 循环中使用了sleep休眠了半小时就中断了_线程中断不是你想中断就能的...

    为什么不强制停止 如何用 interrupt 停止线程 sleep 期间能否感受到中断 停止线程的方式有几种 总结 启动线程需要调用 Thread 类的 start() 方法,并在 run() 方法中 ...

  2. 线程池如何保证所有子线程运行完再执行主线程

    Java主线程等待所有子线程执行完毕在执行,其实在我们的工作中经常的用到,比如说主线程要返回一个响应用户的值,但这个值得赋值过程是由过个子线程来完成的(模拟一个实际开发的情景),所以主线程必须等待子线 ...

  3. java线程中断和终止线程运行

    ava中启动一个线程很容易,通常情况下我们都是等到任务运行结束后让线程自行停止.但有时需要在任务正在运行时取消他们,使得线程快速结束.对此Java并没有提供任何机制.但是我们可以通过Java提供的线程 ...

  4. 有赞一面:还有任务没执行,线程池被关闭怎么办?

    说在前面 在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如极兔.有赞.希音的面试资格,遇到一几个很重要的面试题: 还有线程池正在执行的任务和线程,如果线程池shutd ...

  5. Kotlin的协程,延时、超时(7秒后超时,并中断执行的任务)

    Kotlin协程 简介: 优点:写法很简单,轻量级,挂起几乎不消耗内存,速度上优于java的线程,性能损耗小,能大幅度提高并发性能,本人推荐使用协程,而不用传统的线程 GlobalScope是生命周期 ...

  6. python多线程的使用(导入线程模块、创建子线程任务、启动子线程任务、获取当前执行的线程号)

    1. 导入线程模块 #导入线程模块 import threading 2. 线程类Thread参数说明 Thread([group [, target [, name [, args [, kwarg ...

  7. 【Android 异步操作】Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 )

    文章目录 一.判定当前线程是否是主线程 二.子线程中执行主线程方法 三.主线程中执行子线程方法 一.判定当前线程是否是主线程 在 Android 中 , 如果要判定当前线程是否是主线程 , 可以使用如 ...

  8. ansible-playbook如何判断并中断执行

    今天碰到一个需求,当使用ansible-playbook在执行一个脚本后,根据脚本返回的内容判断是否继续往下执行还是中断执行,查询官网发现使用register寄存器可以实现记录脚本输出,使用when+ ...

  9. python编程(你的电脑能够执行多少线程和进程)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 对python比较熟悉的同学,相信都写过多线程和多进程的代码.可是,不知道大家有没有这么一个想法 ...

最新文章

  1. oracle10g索引不生效,oracle 10g分区表索引失效测试
  2. vscode配置记录
  3. seaborn可视化散点图并自定义可视化结果图像的大小(Change the Size of a Seaborn Plot)
  4. if vue 跳出_vue使用v-if v-show 页面闪烁
  5. Servlet调用流程
  6. 轻松搞定RabbitMQ(二)——工作队列之消息分发机制
  7. linux编程问题记录
  8. 毕业论文word排版设置
  9. elasticsearch-analysis-ik-1.10.0中文分词插件安装
  10. xx信息管理系统设计
  11. IPSEC是如何穿越NAT的
  12. C++笔记---函数声明(prototype)
  13. libav(ffmpeg)简明教程(1)
  14. ASP.NET Ajax 实现无刷新分页
  15. Java -- Servlet面试题及答案(需更深入了解)
  16. 摄影后期从入门到精通(一)
  17. 项目管理手记(七)--DRP系统的文化输出与营销
  18. 【电蜂优选科普】USB数据线接口有哪些类型呢?
  19. 如何将前端echats 图表插入到execl 中
  20. Mac百度云盘不限速操作步骤

热门文章

  1. 在组织中为IT部门构建小型冠军的最快方法
  2. 医生们团结一致,以增加对优质健康信息的访问
  3. Bootstrap 折叠插件
  4. Bootstrap 禁用导航链接
  5. Bootstrap 表单控件的状态
  6. array用法 numpy_python--numpy(3)
  7. Linux内核原理与分析-第二周作业
  8. IP trie树接口
  9. Python图像处理库:Pillow 初级教程
  10. [转]ubuntu apt错误解决办法