结合interrupt state来理解interrupt

[TOC]

Thread类的interrupt方法倒是见过好几次,但是一直不知道他的具体是干什么的,今天查了以下api和core java大概解决了自己的疑惑。(顺便吐槽一下core java的翻译,问题实在不少)

一、关于interrupt state

There is boolean flag in every thread that indicating the interrupt state,When the interrupt method is called on a thread, the interrupted status of the thread is set. --core java
每个线程都有一个布尔变量表示线程的中断状态,当线程调用interrupt后,线程的中断状态会设置.
另外,中断状态 可以通过线程的isInterrupted()返回值来判定,true表示设置为中断状态,false表示非中断状态;
The interrupt method can be used to request termination of a thread.   --core java
interrupt方法可以请求中断一个线程(也就是说只是请求中断,并不能直接中断).

以下代码验证了上述结论,可以看到程序的输出会出现这种情况:首先为false,interrupt以后,变为true,但是程序依旧会输出0到9;

private void simpleInterrupt() {
    Thread t = new Thread(){
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println(i);
            }
        }
    };

    t.start();
    System.out.println("before interrupt:" + t.isInterrupted());
    t.interrupt();
    System.out.println("after interrupt:" + t.isInterrupted());
}

由此可见,interrupt并不像它的中文意思中断一样能中断线程,但是改变了isInterrupted方法的返回值,这个还是可以作为run方法的循环结束的条件,从而中断线程,代码如下:

private void simpleInterruptAffect() {
    Thread t = new Thread(){
        @Override
        public void run() {
            for (int i = 0; i < 100 && !isInterrupted(); i++) {
                System.out.println(i);
            }
        }
    };

    t.start();
    try {
        Thread.sleep(5);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    t.interrupt();
}

多运行几遍,发现i没到99就结束了。

二、sleep、wait等方法和interrupt的联系

1. If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.  --doc
当线程由于sleep或者wait等方法阻塞时,如果调用了interrupt方法,就会抛出一个异常(补充:core java上说是由于系统无法检测处于阻塞状态线程的interrupt state),并且清除掉线程的interrupt status(使得isInterrupted方法返回false),用代码验证一下:

 private void interruptSleep() {
   Thread t1 = new Thread() {
           @Override
           public void run() {
               try {
                Thread.sleep(1000);
                } catch (InterruptedException e) {
                System.out.println("interrupt status in catch:" + isInterrupted());
                }
            }
    };
    t1.start();
    System.out.println("interrupt status before interrupt:" + t1.isInterrupted());
    t1.interrupt();
    System.out.println("interrupt status after interrupt:" + t1.isInterrupted());

}

一般会依次输出
interrupt status before interrupt:false
interrupt status after interrupt:true
interrupt status in catch:false
2. 线程不能睡眠的原因
If you call the sleep method when the interrupted status is set, it doesn’t sleep. Instead, it
clears the status and throws an InterruptedException.
如果线程睡眠前线程它的isInterrupted返回true,线程就不会睡眠,相反,线程的会清除掉interrupt status并且抛出一个异常。同样用代码验证一下。

volatile boolean flag = false;
private void interruptThenSleep() {

    Thread t = new Thread(){
        @Override
        public void run() {
            while(!flag){}
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                System.out.println("interrupt status in catch:" + isInterrupted());
            }
        }
    };

    t.start();
    t.interrupt();
    System.out.println("interrupt status after interrupt:" + t.isInterrupted());
    flag = true;

}

t线程不会休眠10s
并且输出:
interrupt status after interrupt:true
interrupt status in catch:false
到这里可也以得出结论:只要线程的isInterrupted()返回true,Thread.sleep()都会抛出异常,并且清除线程的中断状态。

3.关于interrupted
Tests whether the current thread has been interrupted. The interrupted status of the thread is cleared by this method.  --doc

检测当前线程是否处于中断状态,调用后中断状态会重置(状态变量变为false)

同样验证一下

package com.basic;

/**
 * Created by liouville on 3/25/16.
 */
public class CompareInterrupt {

    volatile static  boolean flag = true;
    public static void main(String[] args) {

        MyThread t = new MyThread();
        t.start();

        System.out.println("主线程:" + t.isInterrupted());
        t.interrupt();

        flag = false;
    }

    private static class MyThread extends Thread{
        @Override
        public void run() {
            super.run();
            System.out.println("run...");

            while (flag){yield();}
            System.out.println(isInterrupted());
            System.out.println(interrupted());
            System.out.println(isInterrupted());
        }
    }
}

一般输出:
主线程:false
run...
true
true
false

三、interrupt interrupted isInterrupted

现在可以更清晰的看到三者之间的区别。
interrupt用来请求中断线程,但是只是设置一下线程的中断状态的标记变量,并不会直接中断线程。
isInterrupted用来判断
调用该方法的线程
是否处于中断状态,处于中断状态返回true,否则false;,不会影响这个中断状态标记变量的值。
interrupted是一个静态方法,也是用来检测当前线程是否处于中断状态,处于中断状态返回true,否则false,但是它会重置中断状态的标记变量为false.**

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容