原博客地址:
多线程编程 实战篇 (四)

不客气地说,至少有一半人认为,线程的”中断”就是让线程停止。
如果你也这么认为,那你对多线程编程还没有入门。

在java中,线程的中断(interrupt)只是改变了线程的中断状态,至于这个中断状态改变后带来的结果,那是无法确定的,有时它更是让停止中的线程继续执行的唯一手段。不但不是让线程停止运行,反而是继续执行线程的手段。

对于执行一般逻辑的线程,如果调用它的interrupt()方法,那么对这个线程没有任何
影响,比如线程a正在执行:
while(条件) x ++;
这样的语句,如果其它线程调用a.interrupt();那么并不会影响a对象上运行的线程,但中断标志会变为true。如果在其它线程里再次测试a的中断状态,则中断标志为true,但并不会停止这个线程的运行。

在一个线程对象上调用interrupt()方法,真正有影响的是wait,join,sleep方法,当然这三个方法包括它们的重载方法。

请注意:[上面这三个方法都会抛出InterruptedException],记住这句话,下面我会重复。一个线程在调用interrupt()后,自己不会抛出InterruptedException异常,所以你看到interrupt()并没有抛出这个异常,所以我上面说如果线程a正在执行while(条件) x ++;你调用a.interrupt()后线程会继续正常地执行下去.
附:
Thread.sleep()源码:

public static native void sleep(long millis) throws InterruptedException;

Object.wait()源码:

public final native void wait(long timeout) throws InterruptedException;

Thread.join()源码

public final synchronized void join(long millis) throws InterruptedException {
...
}

但是,如果一个线程被调用了interrupt()后,它的状态是阻塞状态的。而且这个状态是由于正在执行wait,join,sleep的线程导致的,那么是会改变线程的运行结果.

一. 对于wait中的等待notify、notifyAll换新的线程,其实这个线程已经“暂停”执行,因为它正在某一对象的休息室中,这时如果它的中断状态被改变,那么它就会抛出异常。这个InterruptedException异常不是线程抛出的,而是wait方法,也就是对象的wait方法内部会不断检查在此对象上休息的线程的状态,如果发现哪个线程的状态被置为已中断,则会抛出InterruptedException,意思就是这个线程不能再等待了,其意义就等同于唤醒它了,然后执行catch中的代码。

这里唯一的区别是,被nortify/All唤醒的线程会继续执行wait下面的语句,而在wait
中被中断的线程则将控制权交给了catch语句。一些正常的逻辑要被放到catch中来运行。但有时这是唯一手段,比如一个线程a在某一对象b的wait中等待唤醒,其它线程必须获取到对象b的监视锁才能调用b.notify()[All],否则你就无法唤醒线程a,但在任何线程中可以无条件地调用a.interrupt();唤醒后的逻辑你要放在catch中,当然同notify/All一样,继续执行a线程的条件还是要等拿到b对象的监视锁。

二. 对于sleep中的线程,如果你调用了Thread.sleep(一年);现在你后悔了,想让它早
些醒过来,调用interrupt()方法就是唯一手段,只有改变它的中断状态,让它从sleep中将控制权转到处理异常的catch语句中,然后再由catch中的处理转换到正常的逻辑。同样,对于join中的线程你也可以这样处理。

对于一般介绍多线程模式的书上,他们会这样来介绍:当一个线程被中断后,在进入wait,sleep,join方法时会抛出异常。是的,这一点也没有错,但是这有什么意义呢?如果你知道那个线程的状态已经处于中断状态,为什么还要让它进入这三个方法呢?当然有时是必须这么做的,但大多数时候没有这么做的理由,所以我上面主要介绍了在已经调用这三个方法的线程上调用interrupt()方法让它从这几个方法的”暂停”状态中恢复过来。这个恢复过来就可以包含两个目的:
一. [可以使线程继续执行],那就是在catch语句中执行醒来后的逻辑,或由catch语句
转回正常的逻辑。总之它是从wait,sleep,join的暂停状态活过来了。
二. [可以直接停止线程的运行],当然在catch中什么也不处理,或return,那么就完成了当前线程的使命,可以使在上面”暂停”的状态中立即真正的”停止”。

Thread.interrupt()方法理解的更多相关文章

  1. 注意Thread.interrupt()方法的真正作用并不是用来中断线程

      程序是很简易的.然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决,将导致意外的行为以及细微的.难以发现的错误.      在本篇文章中,我们针对这些难题之一:如何中断一个正在 ...

  2. 调用Thread.interrupt()方法到底会发生什么?

    1. 当线程处于Blocked状态(sleep,wait,join),线程会退出阻塞状态,并抛出一个InterruptedException.park除外,它有响应但是不会抛出异常 2. 当线程处于R ...

  3. Thread interrupt方法解析

    初步理解 我们在看一些多线程代码的时候,有的时候会碰到使用interrupt()方法的时候.从字面的意思来理解,应该就是中断当前正在执行的线程.那么,对于一个我们设计的普通线程来说,如果我们在主线程里 ...

  4. Java Thread.interrupt 害人! 中断JAVA线程(zz)

    http://www.blogjava.net/jinfeng_wang/archive/2012/04/22/196477.html#376322 ————————————————————————— ...

  5. 停止Java线程,小心interrupt()方法

    来源:http://blog.csdn.net/wxwzy738/article/details/8516253 程序是很简易的.然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决 ...

  6. Java线程停止interrupt()方法

    程序是很简易的.然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决,将导致意外的行为以及细微的.难以发现的错误.在本篇文章中,我们针对这些难题之一:如何中断一个正在运行的线程. 中 ...

  7. 多线程 interrupt()方法

    java interrupt()方法只是设置线程的中断标记,当对处于阻塞状态的线程调用interrupt方法时(处于阻塞状态的线程是调用sleep, wait, join 的线程),会抛出Interr ...

  8. Thread interrupt() 线程中断的详细说明

    GitHub源码地址 原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止 ...

  9. 关于Thread类中三个interrupt方法的研究与学习(转)

    先看三个方法原型: public void interrupt(): public boolean isInterrupted(): public static boolean interrupted ...

随机推荐

  1. (转)Linux服务器安装配置tomcat

    这里首先说明下,Linux下的Tomcat没有32位和64位的区分. tomcat是分windows版本与linux版本的,windows版本一般以exe或者zip格式:linux版本一般以tar.g ...

  2. 项目中ApplicationContext

    applicationContext说白了就是对beanFactory的扩展,也就是一个spring容器,而且applicationContext是单例的,项目中主要包含一个webApplicatio ...

  3. pick定理详解

    一.概念 假设P的内部有I(P)个格点,边界上有B(P)个格点,则P的面积A(P)为:A(P)=I(P)+B(P)/2-1. 二.说明 Pick定理主要是计算格点多边形(定点全是格点的不自交图形)P的 ...

  4. HDU5734 Acperience(数学推导)

    Problem Description Deep neural networks (DNN) have shown significant improvements in several applic ...

  5. Xamarin.Forms(一) Visual Studio 连接安卓模拟器(逍遥安卓)

    刚开始学习Xamarin.Forms的时候总是比较困难的,连接安卓模拟器就花了我好长时间,后来在网上找到了方法: 1.打开adb.exe所在目录: 如:cd F:\Android\android-sd ...

  6. 用 Node.js 把玩一番 Alfred Workflow

    插件地址(集成Github.掘金.知乎.淘宝等搜索) 作为 Mac 上常年位居神器榜第一位的软件来说,Alfred 给我们带来的便利是不言而喻的,其中 workflow(工作流) 功不可没,在它上面可 ...

  7. swift 获取文件的Md5值

    获取文件的Md5值的方法如下 func md5File(url: URL) -> String? { let bufferSize = 1024 * 1024 do { //打开文件 let f ...

  8. HDU 4372 Count the Buildings:第一类Stirling数

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4372 题意: 有n栋高楼横着排成一排,各自的高度为1到n的一个排列. 从左边看可以看到f栋楼,从右边看 ...

  9. android 学习 ListView使用补充

    前面两篇学习适配器的时候用的就是listview,主要是简单的添加,今晚在看了下listview滚动状态事件和动态加载数据,一个小demo. listview的滚动状态主要有三种,onScrollSt ...

  10. Git基础命令的使用

    当前git版本: git version 2.9.2.windows.1 1.创建一个能与git服务器连接的本地git库 本地:  git init git status (-s) git add . ...