interrupt()和interrupted()以及isInterrupted()

原创 2018年04月17日 15:00:28

这一篇着重分析下线程中断,在C.U.T中,中断是用的比较多的一种技术手段,运用的好能带来很多的便利。

1.interrupt()

    public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();

        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();           // Just to set the interrupt flag
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }

1.如果不是当前线程中断自己,需要checkAccess。

2.如果线程在调用Object类的wait(),join(),sleep()方法过程中受阻,则其中断状态将被清除,同时还收到一个InterruptException。

3.如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException。

4.如果该线程在一个 Selector 中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的 wakeup 方法一样。

备注:3,4两点本人没什么经验,上述的描述是从jdk api摘抄过来的。一般大家注意下第二点就行。

2.interrupted()

测试当前线程是否已中断。线程的中断状态由该方法擦除。也就是如果两次调用该方法,则第二次会返回false

    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }

3.isInterrupted()

测试线程是否已被中断,但是线程的状态不受此方法影响。也就是说这个方法不会进行擦除操作

    public boolean isInterrupted() {
        return isInterrupted(false);
    }
主要的区分就是isInterrupt的调用参数,一个数true,一个是false。
    /**
     * Tests if some Thread has been interrupted.  The interrupted state
     * is reset or not based on the value of ClearInterrupted that is
     * passed.
     */
    private native boolean isInterrupted(boolean ClearInterrupted);

以上就是api内对3个方法的解释,我相信已经很清楚了,没有必要做过多的解释。

以下就是进行一些测试,来分析一下自己的理解。

测试一、使用isInterrupted判断线程状态

public class TestA {
    public static void main(String[] args) {

        T2 t2 = new T2();
        t2.start();

        try{
            Thread.sleep(2000); //主线程执行2S睡眠,保证t2线程能够正常执行一段时间
        }catch (Exception e){
            System.out.println("main exception");
        }

        t2.interrupt(); //通知t2,你中断了

    }
}

class T2 extends Thread {

    @Override
    public void run()
    {
        while (true){
            if(Thread.currentThread().isInterrupted()){
                System.out.println("111111111");
            }else {
                System.out.println("22222222");
            }
            System.out.println("33333333333333");
        }
    }
}
22222222
33333333333333
22222222
33333333333333
22222222
33333333333333
...
...
111111111
33333333333333
111111111
33333333333333
111111111
33333333333333
...
...

结果分析:

可以看见在main线程睡眠的那2秒中内,t2线程在正常执行(输出2,3),当t2进行了中断操作时,输出了(1,3),而我们调用的是isInterrupted方法,这个方法是不会擦除状态的,同时也要注意,t2线程一直在运行中,没有真正的中断。只是有了一个中断状态而已。

在Core Java中有这样一句话:"没有任何语言方面的需求要求一个被中断的程序应该终止。中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断 "

测试二、阻塞方法调用时执行interrupt

public class TestA {
    public static void main(String[] args) {

        T2 t2 = new T2();
        t2.start();

        try{
            Thread.sleep(6000); //主线程执行2S睡眠,保证t2线程能够正常执行一段时间
        }catch (Exception e){
            System.out.println("main exception");
        }

        t2.interrupt(); //通知t2,你中断了

    }
}

class T2 extends Thread {

    @Override
    public void run()
    {
        System.out.println("t2 into sleeping");
        try{
            Thread.sleep(20000);
            System.out.println("t2 wake up");
        }catch (InterruptedException e){
            System.out.println("oh,shit! exception");
            return;
        }
        System.out.println("oh,shit! exception");
    }
}
t2 into sleeping
oh,shit! exception

此测试用例就是测试interrupt方法中API的关于wait,join,sleep方法,如果在调用时发出interrupt指令时,会直接抛出InterruptException。

测试三、阻塞方法调用前执行interrupt方法

public class TestA {
    public static void main(String[] args) {
        System.out.println("main start");
        Thread.currentThread().interrupt();
        try{
            System.out.println("main exe sleep");
            Thread.sleep(6000); //主线程执行2S睡眠,保证t2线程能够正常执行一段时间
            System.out.println("after main exe sleep");
        }catch (InterruptedException e){
            System.out.println("oh! shit Exception");
        }
        System.out.println("main end");
    }
}
main start
main exe sleep
oh! shit Exception
main end
也可以很明显的看见,当主线程执行过interrupt方法之后,如果再执行sleep,wait,join等方法的话,会得到一个InterruptException。
测试四:isInterrupted方法的细节测试
public class TestA {
    public static void main(String[] args) {
        System.out.println("main start");
        Thread.currentThread().interrupt();
        try{
            System.out.println("main exe sleep");
            System.out.println("main state111:  "+Thread.currentThread().isInterrupted());
            Thread.sleep(6000); //主线程执行2S睡眠,保证t2线程能够正常执行一段时间
            System.out.println("after main exe sleep");
        }catch (InterruptedException e){
            System.out.println("oh! shit Exception");
            System.out.println("main state222:  "+Thread.currentThread().isInterrupted());
            System.out.println("main state333:  "+Thread.currentThread().isInterrupted());
        }
        System.out.println("main end");
    }
}
main start
main exe sleep
main state111:  true
oh! shit Exception
main state222:  false
main state333:  false
main end
我们发现,isInterrupted方法只能使用一次,第一次使用时能发现线程处于中断状态了,但是当执行过sleep之后呢,中断状态被擦除了,因此再次判断肯定是false。
测试五、测试interrupted方法
public class TestA {
    public static void main(String[] args) {
        System.out.println("main start");
        System.out.println("main state11:  "+Thread.interrupted());
        Thread.currentThread().interrupt();
        System.out.println("main state22:  "+Thread.interrupted());
        System.out.println("main state33:  "+Thread.interrupted());
        System.out.println("main end");
    }
}
main start
main state11:  false
main state22:  true
main state33:  false
main end
可以发现,当第一次当第二次调用时,可以判断出当前线程处于中断状态了,但是再一次调用时确发现返回了false,因为它做了擦除动作。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_32924343/article/details/79971109

分布式爬虫以及Scrapy源码剖析

-
  • 1970年01月01日 08:00

interrupted() 和 isInterrupted() 的区别

Thread 类中提供了两种方法用来判断线程的状态是不是停止的。就是我们今天的两位主人公 interrupted() 和 isInterrupted() 。interrupted() 官方解释:测...
  • github_34889651
  • github_34889651
  • 2016-09-08 20:39:47
  • 709

对于interrupt,interrupted 和 isInterrupted的一些理解

为什么interrupt,isInterrupted是实例方法,而interrupted是类方法? 原因: interrupt的语义 是:中断一个线程。线程可以在其内部调用this.interru...
  • sjtu_huang
  • sjtu_huang
  • 2011-09-17 17:04:45
  • 4721

Thread类的interrupt(),interrupted(),isInterrupted()

1. sleep() & interrupt() 线程A正在使用sleep()暂停着: Thread.sleep(100000); 如果要取消他的等待状态,可以在正在执行的线程里(比如这里是B...
  • bingjing12345
  • bingjing12345
  • 2013-03-02 18:43:11
  • 4504

interrupt、interrupted 、isInterrupted 区别

1、interrupt  interrupt方法用于中断线程。调用该方法的线程的状态为将被置为"中断"状态。 注意:线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状态为并...
  • z69183787
  • z69183787
  • 2014-05-05 20:27:53
  • 21396

分享一个:interrupt、interrupted和isInterrupted的区别,写的很好

1、interrupt()  interrupt方法用于中断线程。调用该方法的线程的状态为将被置为"中断"状态。  注意:线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状...
  • F1576813783
  • F1576813783
  • 2017-08-05 11:43:58
  • 234

JAVA interrupt、interrupted和isInterrupted的区别

提前总结: interrupt() 向当前调用者线程发出中断信号 isinterrupted() 查看当前中断信号是true还是false interrupted() 是静态方法,查...
  • QPC908694753
  • QPC908694753
  • 2017-03-11 11:24:44
  • 1613

【Java】interrupt、interrupted和isInterrupted的区别

今天在看到Thread类的isInterrupted方法可以获取线程的中断状态: 于是写了个例子想验证一下: public class Interrupt { public static vo...
  • hj7jay
  • hj7jay
  • 2016-12-05 10:15:45
  • 2645

Java中的线程中断:interrupt()、interrupted()和isInterrupted

使用interrupt()中断线程当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。这里...
  • u010412719
  • u010412719
  • 2015-10-25 20:51:04
  • 1996

Thread.interrupted()与Thread.isInterrupted()的区别

调用Thread.interrupt()方法并不能真正停止线程,只是在当前线程做了一个中断的状态标志。public class MyThread extends Thread{ @Overrid...
  • fjse51
  • fjse51
  • 2017-01-04 16:04:30
  • 2900
收藏助手
不良信息举报
您举报文章:interrupt()和interrupted()以及isInterrupted()
举报原因:
原因补充:

(最多只允许输入30个字)