一个线程在未正常结束之前, 被强制终止是很危险的事情. 因为它可能带来完全预料不到的严重后果. 所以你看到Thread.suspend, Thread.stop等方法都被Deprecated了.
那么不能直接把一个线程搞挂掉, 但有时候又有必要让一个线程死掉, 或者让它结束某种等待的状态 该怎么办呢? 优雅的方法就是, 给那个线程一个中断信号, 让它自己决定该怎么办. 比如说, 在某个子线程中为了等待一些特定条件的到来, 你调用了Thread.sleep(10000), 预期线程睡10秒之后自己醒来, 但是如果这个特定条件提前到来的话, 你怎么通知一个在睡觉的线程呢? 又比如说, 主线程通过调用子线程的join方法阻塞自己以等待子线程结束, 但是子线程运行过程中发现自己没办法在短时间内结束, 于是它需要想办法告诉主线程别等我了. 这些情况下, 就需要中断. 
中断是通过调用Thread.interrupt()方法来做的. 这个方法通过修改了被调用线程的中断状态来告知那个线程, 说它被中断了. 对于非阻塞中的线程, 只是改变了中断状态, 即Thread.isInterrupted()将返回true; 对于可取消的阻塞状态中的线程, 比如等待在这些函数上的线程, Thread.sleep(), Object.wait(), Thread.join(), 这个线程收到中断信号后, 会抛出InterruptedException, 同时会把中断状态置回为false.
下面的程序会演示对非阻塞中的线程中断:

public class Thread3 extends Thread{
public void run(){
while(true){
if(Thread.interrupted()){
System.out.println("Someone interrupted me.");
}
else{
System.out.println("Going...");
}
long now = System.currentTimeMillis();
while(System.currentTimeMillis()-now<1000){
// 为了避免Thread.sleep()而需要捕获InterruptedException而带来的理解上的困惑,
// 此处用这种方法空转1秒
}
}
} public static void main(String[] args) throws InterruptedException {
Thread3 t = new Thread3();
t.start();
Thread.sleep(3000);
t.interrupt();
}
}

下面的程序演示的是子线程通知父线程别等它了:

public class Thread4 extends Thread {
private Thread parent;
public Thread4(Thread parent){
this.parent = parent;
} public void run() {
while (true) {
System.out.println("sub thread is running...");
long now = System.currentTimeMillis();
while (System.currentTimeMillis() - now < 2000) {
// 为了避免Thread.sleep()而需要捕获InterruptedException而带来的理解上的困惑,
// 此处用这种方法空转2秒
}
parent.interrupt();
}
} public static void main(String[] args){
Thread4 t = new Thread4(Thread.currentThread());
t.start();
try {
t.join();
} catch (InterruptedException e) {
System.out.println("Parent thread will die...");
}
}
}

中断状态可以通过 Thread.isInterrupted()来读取,并且可以通过一个名为 Thread.interrupted()的静态方法读取和清除状态(即调用该方法结束之后, 中断状态会变成false)。
由于处于阻塞状态的线程 被中断后抛出exception并置回中断状态, 有时候是不利的, 因为这个中断状态可能会作为别的线程的判断条件, 所以稳妥的办法是在处理exception的地方把状态复位:

boolean interrupted = false;
try {
while (true) {
try {
return blockingQueue.take();
} catch (InterruptedException e) {
interrupted = true;
}
}
} finally {
if (interrupted){
Thread.currentThread().interrupt();
}
}

当代码调用中须要抛出一个InterruptedException, 你可以选择把中断状态复位, 也可以选择向外抛出InterruptedException, 由外层的调用者来决定.

不是所有的阻塞方法收到中断后都可以取消阻塞状态, 输入和输出流类会阻塞等待 I/O 完成,但是它们不抛出 InterruptedException,而且在被中断的情况下也不会退出阻塞状态. 

尝试获取一个内部锁的操作(进入一个 synchronized 块)是不能被中断的,但是 ReentrantLock 支持可中断的获取模式即 tryLock(long time, TimeUnit unit)。

java线程中断2的更多相关文章

  1. 一文搞懂 Java 线程中断

    在之前的一文<如何"优雅"地终止一个线程>中详细说明了 stop 终止线程的坏处及如何优雅地终止线程,那么还有别的可以终止线程的方法吗?答案是肯定的,它就是我们今天要分 ...

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

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

  3. Java线程中断的本质深入理解(转)

    一.Java中断的现象 首先,看看Thread类里的几个方法: public static boolean interrupted 测试当前线程是否已经中断.线程的中断状态 由该方法清除.换句话说,如 ...

  4. java线程中断的办法

    目录 中断线程相关的方法 中断线程 for循环标记退出 阻塞的退出线程 使用stop()方法停止线程 中断线程相关的方法 中断线程有一些相应的方法,这里列出来一下. 注意,如果是Thread.meth ...

  5. Java线程中断理解(interrupte)

    Java线程之中,一个线程的生命周期分为:初始.就绪.运行.阻塞以及结束.当然,其中也可以有四种状态,初始.就绪.运行以及结束. 一般而言,可能有三种原因引起阻塞:等待阻塞.同步阻塞以及其他阻塞(睡眠 ...

  6. Java线程中断的本质深入理解

    Java的中断是一种协作机制.也就是说调用线程对象的interrupt方法并不一定就中断了正在运行的线程,它只是要求线程自己在合适的时机中断自己. 一.Java中断的现象 首先,看看Thread类里的 ...

  7. java线程中断[interrupt()函数] (转载)

    一个正常的线程中断: 从运行到真正的结束,应该有三个阶段: 正常运行. 处理结束前的工作,也就是准备结束. 结束退出. Java曾经提供过抢占式限制中断,但问题多多,例如的Thread.stop.另一 ...

  8. java线程中断

    public void Thread.interrupt() // 无返回值 public boolean Thread.isInterrupted() // 有返回值 public static b ...

  9. lesson6:java线程中断

    正常的情况下,业务系统都不会去中断它的线程,但是由于一些特殊情况的发生,线程已经不能正常结束了,并且此类线程已经影响到业务系统提供服务的能力,如果系统设计的健壮,便会通过监控线程去主动的中断此类线程. ...

随机推荐

  1. vue移动端地址三级联动组件(二)

    继续上一篇: 子组件css: <style scoped lang="less"> #city { width: 100%; height: 100%; positio ...

  2. [Luogu] P4198 楼房重建

    题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个 ...

  3. PAT 1098. Insertion or Heap Sort

    According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and gr ...

  4. 一个电商项目的Web服务化改造7:Dubbo服务的调用,4个项目

    使用dubbo服务的过程,很简单,和之前学习的WebService完全一样,和本地接口调用也基本一致. dubbo和WebService的区别:我认为dubbo就是封装了WebService,然后提供 ...

  5. 【Codeforces Global Round 1 E】Magic Stones

    [链接] 我是链接,点我呀:) [题意] 你可以把c[i]改成c[i+1]+c[i-1]-c[i] (2<=i<=n-1) 问你能不能把每一个c[i]都换成对应的t[i]; [题解] d[ ...

  6. 【[Offer收割]编程练习赛12 C】矩形分割

    [题目链接]:http://hihocoder.com/problemset/problem/1495 [题意] [题解] 把每个方块都再分成3*3的小块; 这样; 对于一个方块来说 如果是'\' 则 ...

  7. hibernate 中映射关系配置

    多对多 : 外键维护权,一方放弃inverse="true",并且不放弃维护权的一方,加入 cascade="save-update":推荐方案 Student ...

  8. windows 2013(codevs 1695)

    题目描述 Description 话说adamyi编的Windows 2013超时了(- -!),所以他不得不在自己家门口亲眼见证这个电影般的场景.虽然他不想错过这个美妙的时刻,但是他的肚子一再抗议, ...

  9. MSXML2

    The following C/C++ example creates and appends a new text node to the root document element. #impor ...

  10. 【ACM】nyoj_47_过桥问题_201308151616

    过河问题时间限制:1000 ms  |  内存限制:65535 KB 难度:5描述 在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边.如果不借助手电筒的话,大家是无论如何也不敢过桥去的.不幸的 ...