在 java中启动线程非常容易,大多数情况下是让一个线程执行完自己的任务然后自己停掉。一个线程在未正常结束之前, 被强制终止是很危险的事情. 因为它可能带来完全预料不到的严重后果,比如会带着自己所持有的锁而永远的休眠,迟迟不归还锁等。在当前的api中,Thread.suspend、Thread.stop等方法都被Deprecated了,线程只能用interrupt中断,而且不是立刻中断,只是发了一个类似于信号量的东西,通过修改了被调用线程的中断状态来告知那个线程, 说它被中断了,至于什么时候中断,这个有系统判断,会在一个合适的时候进行中断处理。

/*** Created by Zero on 2017/8/17.*/
public class ThreadTest1 {public static void main(String[] args) {NThread nThread = new NThread(); System.out.println("interrupt执行前"); nThread.start(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } nThread.interrupt(); System.out.println("interrupt执行后"); } /** * 测试多线程的中断机制 */ static class NThread extends Thread{ @Override public void run() { super.run(); while(true){ System.out.println("依然存活..."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }

在上面代码中,线程睡醒之后,调用thread线程的interrupt方法,catch到InteruptedException,设置标志位。interrupt()方法相当于线程睡着的时候一盆凉水来吵醒它,线程表示不开心,并向你抛出一个大大的异常以示不满。

  • 首先:线程中断是一种协作机制,调用线程对象的interrupt方法并不一定就中断了正在运行的线程,它只是要求线程自己在合适的时间中断自己。
  • 其次:任务的方法必须是可中断的,即方法必须抛出InterruptedException。

由此可见,interrupt() 方法并不能立即中断线程,该方法仅仅告诉线程外部已经有中断请求,至于是否中断还取决于线程自己。在Thread类中除了interrupt() 方法还有另外两个非常相似的方法:interrupted 和 isInterrupted 方法,下面来对这几个方法进行说明:

  • interrupt 此方法是实例方法,用于告诉此线程外部有中断请求,并且将线程中的中断标记设置为true,而不是立即中断。
  • interrupted 此方法是类方法,用来判断当前线程是否已经中断。线程的中断状态由该方法清除。
  • isInterrupted 此方法是实例方法,用来判断线程是否已经中断。线程的中断状态不受该方法的影响。

总结:java线程中断机制通过调用Thread.interrupt() 方法来做的,这个方法通过修改了被调用线程的中断状态来告知那个线程说它被中断了。对于非阻塞中的线程,只是改变了中断状态,即Thread.isInterrupted() 将返回true;对于可取消的阻塞状态中的线程,比如等待在这些函数上的线程,Thread.sleep()、Object.wait()、Thread.join(), 这个线程收到中断信号后,会抛出InterruptedException,同时会把中断状态置回为true。但调用Thread.interrupted()会对中断状态进行复位。

/*** Created by Zero on 2017/8/17.*/
public class ThreadTest1 { public static void main(String[] args) { NThread nThread = new NThread(); nThread.start(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("cancel执行前" + System.currentTimeMillis()); nThread.cancel(); } /** * 测试多线程的中断机制 */ static class NThread extends Thread { private boolean isCancel; @Override public void run() { while (!isCancel) { System.out.println("依然存活..."); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); Thread.currentThread().interrupt(); } } System.out.println("while结束" + System.currentTimeMillis()); } public void cancel() { this.isCancel = true; } } }

执行结果:

依然存活...
cancel执行前1502964413042
while结束1502964415042

机智的你,此刻一定发现执行前后相差2000毫秒,难道cancel()方法执行了2000毫秒?这纯属扯淡,里面没有任何耗时操作,就是一个赋值而已,其实是子线程的退出,前提条件是while循环结束,当且仅当cancel标示设置为true的瞬间立马执行while的判断,此时的时间差才可以忽略不计(1毫秒内),但是当我们调用cancel方法将isCancel 标记设置为true 时,while循环里面有一个耗时操作(休眠5000毫秒),只有等待耗时操作执行完毕后才会去检查这个标记,所以cancel方法和线程退出中间有时间间隔。

接下来,我们通过interrupt 和 isinterrupt 方法来中断线程,代码如下:

/*** Created by Zero on 2017/8/17.*/
public class ThreadTest1 {public static void main(String[] args) {NThread nThread = new NThread(); nThread.start(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("interrupt执行前"+System.currentTimeMillis()); nThread.interrupt(); } /** * 测试多线程的中断机制 */ static class NThread extends Thread{ @Override public void run() { while(!interrupted()){ System.out.println("依然存活..."); try { Thread.sleep(5000); } catch (InterruptedException e) { System.out.println("InterruptedException"); Thread.currentThread().interrupt(); } } System.out.println("interrupt执行后"+System.currentTimeMillis()); } } }

依然存活...
interrupt执行前1502965915683
InterruptedException
interrupt执行后1502965915683

这次立马中断了,是因为在开启子线程后,经过执行3000毫秒的休眠,线程执行了interrupt 方法,此时子线程的5000毫秒休眠还没结束,就像上述所说的睡眠中被一盆冷水吵醒,很不开心的抛了异常,Thread.currentThread().interrupt() 改变了线程的标记状态,在抛出InterruptedException 的同时,线程的中断标志被清除了,再次执行while循环语句的时候,!interrupted() 此时是false,便不再执行while语句。

此处如果去掉Thread.currentThread().interrupt() ,线程便会无休止的执行下去,此处就不上代码了,就注释掉这一行,运行就可以看到效果,经常看到一些代码在catch中不作任何处理,其实有时候这样是很危险的,此处已经证明。

两点建议: 
1. 除非你知道线程的中断策略,否则不应该中断它。 
2. 任务代码不该猜测中断对执行线程的含义。遇到InterruptedException异常时,不应该将其捕获后“吞掉”,而应该继续向上层代码抛出。

转载于:https://www.cnblogs.com/dengyungao/p/7524757.html

多线程: 多线程中断机制相关推荐

  1. java isinterrupted_JAVA多线程之中断机制stop()、interrupted()、isInterrupted()

    一,介绍 本文记录JAVA多线程中的中断机制的一些知识点.主要是stop方法.interrupted()与isInterrupted()方法的区别,并从源代码的实现上进行简单分析. JAVA中有3种方 ...

  2. java isinterrupted_JAVA多线程之中断机制(stop()、interrupted()、isInterrupted())

    一,介绍 本文记录JAVA多线程中的中断机制的一些知识点.主要是stop方法.interrupted()与isInterrupted()方法的区别,并从源代码的实现上进行简单分析. JAVA中有3种方 ...

  3. JAVA多线程之中断机制(如何处理中断?)

    一,介绍 这篇文章主要记录使用 interrupt() 方法中断线程,以及如何对InterruptedException进行处理.感觉对InterruptedException异常进行处理是一件谨慎且 ...

  4. Java多线程——多线程的基本概念和使用

    一.进程和线程的基础知识 1.进程和线程的概念 进程:运行中的应用程序称为进程,拥有系统资源(cpu.内存) 线程:进程中的一段代码,一个进程中可以有多段代码.本身不拥有资源(共享所在进程的资源) 在 ...

  5. java多线程--多线程基础小结

    什么是线程? 在同一个进程中可以执行多个任务,每一个任务可以看做一个线程. 线程是程序的执行单元,执行路径,使程序使用cpu的最基本单位 一个进程如果只有一条执行路径,那么就是单线程的 一个进程如果有 ...

  6. java多线程中方法_java中多线程 - 多线程中的基本方法

    介绍一下线程中基本的方法使用 线程睡眠sleep() Thread.sleep(毫秒);我们可以通过sleep方法设置让线程睡眠.可以看到sleep是个静态方法 public static nativ ...

  7. java 线程的基本概念_Java多线程——多线程的基本概念和使用

    一.进程和线程的基础知识 1.进程和线程的概念 进程:运行中的应用程序称为进程,拥有系统资源(cpu.内存) 线程:进程中的一段代码,一个进程中可以有多段代码.本身不拥有资源(共享所在进程的资源) 在 ...

  8. java线程知识梳理_Java多线程——多线程相关知识的逻辑关系梳理

    1 学习多线程知识的根本目标 多线程知识的根本目标是:设计稳健的并发程序. 当然,本文无法回答这个实践性很强的问题(这与具体的业务相关,涉及到具体的策略),本文主要阐述相关知识之间的关系,希望初学者不 ...

  9. java中多线程 - 多线程中的基本方法

    介绍一下线程中基本的方法使用 线程睡眠sleep() Thread.sleep(毫秒);我们可以通过sleep方法设置让线程睡眠.可以看到sleep是个静态方法 public static nativ ...

  10. android 单元测试 多线程,多线程之单元测试(Junit)

    多线程测试服务 1.新建一个核心数为100 的线程池 ExecutorService service = Executors.newFixedThreadPool(100); 2.执行一个阻塞不大的任 ...

最新文章

  1. 2018-4-17论文《狼群算法的研究与应用》笔记2 :高维复杂单目标连续优化问题的改进狼群算法
  2. 10月机器学习开源项目Top10
  3. java- ASM 字节码操控框架
  4. 小哥质疑谷歌顶会论文有错,并且拿出了复现代码来证明
  5. Android赚钱的方法--界面嵌入有米广告(持续关注中)
  6. Intellij IDEA2019项目包分层结构显示设置
  7. HighNewTech:70后、80后、90后、95后职场人大数据调查(有趣的五个结论)——源于猎聘网
  8. Delphi XE 10.4 FMX ListView 一个不易察觉的 BUG
  9. svn文件同步到web服务器,即同步到网站根目录
  10. jqplot学习笔记
  11. git常用操作命令整理大全(含github操作)
  12. 《UML中的六大关系》和《Eclipse中如何使用UML方便查看项目框架》
  13. 华为手机明年全面升级鸿蒙OS:其实两年前就能用
  14. HDU1164 Eddy's research I(解法二)
  15. Windows给SVN配置中文语言包
  16. python合并单元格出现:‘MergedCell‘ object attribute ‘value‘ is read-only 如何处理
  17. 7-9 打印倒直角三角形图形
  18. AARRR模型——变现:终极目标(下)
  19. 小程序源码:仿各大APP种树微信小程序源码下载-简单快速上手
  20. 图解数组计算模块NumPy下(三角函数、四舍五入函数(around)、取整、将弧度转化为角度、统计分析函数、中位数、数组的排序、argsort()、lexsort())

热门文章

  1. wttr.in -- a magical website
  2. windows平台源码编译最新版openssl
  3. Lighttpd 搭建 Web 服务器
  4. SuSE配置zypper(功能相当于RHEL中的yum)
  5. Spring Bean实例化的几种特殊方式
  6. hadoop的基本搭建
  7. Linux DHCP服务器
  8. strcat与strncat的C/C++实现
  9. Nginx + uWSGI + Flask + Vhost
  10. 两台设备有三条链路,请问如何添加?