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

背景

今天在研究ThreadPoolExecutor源码时,在runWorker(Worker w)的方法中有一个判断条件分别用到了Thread.interrupted()和Thread.currentThread().isInterrupted() 。一时间看的不是很明白。就写了一个demo研究了一下,这里记录一下研究过程中遇到的问题和总结。
ThreadPoolExecutor.runWorker(Worker w) 的源码:
在这里插入图片描述
因为没有在工作中碰到,不是很明白Thread.interrupted() 和Thread.currentThread().isInterrupted()两者的含义。
分别追了两种的源码,发现两则最终走的是同一个本地私有方法。就是传入的Boolean 参数值相反。下面分别看一下两者的源码:
Thread.interrupted()源码:
在这里插入图片描述
在这里插入图片描述

Thread.currentThread().isInterrupted()源码
在这里插入图片描述
在这里插入图片描述
查看翻译得知:interrupted()会清除线程得中断状态,在中断状态下,多次调用,第一次会返回true表示线程是中断状态,随后会清除线程得中断状态。以后多次调用都会返回false,除非在调用之前线程再次中断。
isInterrupted(),会返回线程得当前状态,不会清理中断线程得中断状态,所以多次调用都会返回同一结果。
通过翻译知道两者得区别,但是还不是很明白。写个demo来加深理解。

演示demo

因为为了明白runWorker(Worker w)中判断条件得意义,我就仿照写了一个简单得例子。代码如下:

public class ThreadInterruptTest {

    public static void main(String[] args) {

        Thread thread = Thread.currentThread();
        thread.interrupt();
    
        if ((Thread.interrupted() && true) && !thread.isInterrupted()) {
            System.out.println("0000000");
            thread.interrupt();
        }
        System.out.println("hahhahahh");
    }

}

演示中遇到的问题

在这里提示一下,使用idea在debug模式下,不要使用Evaluate工具查看结果值。有时候会不准确得。可以看一下我遇到得问题。
在这里插入图片描述
在这里插入图片描述
使用Evaluate 查看得到得判断结果是false,但是代码确走进了判断条件里了。
然后,我有在次运行,分别查看了Thread.interrupted() 和 !thread.isInterrupted() 得结果。返回得一个false,一个true。
在这里插入图片描述
在这里插入图片描述
根据这两个结果,最终是false,按照这个结果不因该走进 if 里面啊。
为了看明白,将判断语句,抽离出来,赋值给一个boolean结果。在断点调试。
在这里插入图片描述
这时可以看到程序运行结果是true,经过流程分析,(线程中断,interrupted()方法会返回true,表明线程中断,并清除线程得中断状态,然后 执行thread.isInterrupted(),因为线程中断状态被清除,所有返回false,然后“!”取反就是true ,最终是 true && true 结果就是true)确实是idea工具问题。

猜想:可能是因为Evaluate 工具执行Thread.interrupted() 得时候,先将线程做了恢复,返回恢复得状态,所以返回得结果是false。不管是什么原因,这里给我上了一课,不要过度依赖工具,相信工具。
就是因为这个工具原因,困扰了我很久。

验证

这里来测试一下源码中的说明,连续调用Thread.interrupted()方法和连续调用thread.isInterrupted()的结果,测试代码如下:

public class ThreadInterruptTest {

    public static void main(String[] args) {
        Thread thread = Thread.currentThread();
        //中断线程
        thread.interrupt();
        //连续调用Thread.interrupted()
        boolean b1 = Thread.interrupted();
        boolean b2 = Thread.interrupted();
        boolean b3 = Thread.interrupted();
        //连续调用thread.isInterrupted()
        boolean b4 = thread.isInterrupted();
        thread.interrupt();
        boolean b5 = thread.isInterrupted();
        boolean b6 = thread.isInterrupted();

        System.out.println("======================");
        boolean b11 = Thread.interrupted();
        thread.interrupt();
        boolean b12 = Thread.interrupted();
        boolean b13 = Thread.interrupted();
        //连续调用thread.isInterrupted()
        boolean b14 = thread.isInterrupted();
        thread.interrupt();
        boolean b15 = thread.isInterrupted();
        boolean b16 = thread.isInterrupted();
        System.out.println("===============");

    }

执行结果。
![![在这里插入图片描述](https://img-blog.csdnimg.cn/20200619193511253.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d5ejA5MjM=,size_16,color_FFFFFF,t_70](https://img-blog.csdnimg.cn/20200619193858439.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d5ejA5MjM=,size_16,color_FFFFFF,t_70

结果分析:

1、一开始线程中断,连续执行Thread.interrupted() 是可以发现,b1返回true;b2和b3返回false。证明了interrupted(),可以清除线程的中断状态,将线程中断转换为运行,但是对运行的线程将不做处理。
2、在执行thread.isInterrupted() 时,b4返回false说明线程在运行状态,然后将线程中断,在连续调用两次thread.isInterrupted() ,结果都是true,说明isInterrupted(),方法只返回线程的中断状态,不会对中断的线程做清除中断状态处理。
3、在看Thread.interrupted() 方法。当执行b11时,线程处于中断状态,执行一次后,会将线程状态由中断转为运行。
然后在将当前线程中断,b12为true,b13为false,说明连续执行两次Thread.interrupted() 结果都返回true,说明在执行第二次之前,线程在次被中断过。

两者的区别:

相同点:

1、两者都是都是Thread类中的方法,
2、两者最终都是调用的是同一个方法,返回结果是boolean值。true 表示线程中断,false表示线程未中断。

不同点:

1、interrupted()是静态方法;
isInterrupted()是非静态方法。
2、interrupted() 的调用者是当前线程对象,
isInterrupted()的调用者可以是任意线程对象。
3、interrupted()调用本地方法是传出的参数值为true,表示返回线程的中断状态,如果线程中断,
会清楚掉线程的中断状态(也就是会将中断状态清楚掉,变成运行状态,运行的状态不做处理)。
isInterrupted()调用本地方法是传出的参数(ClearInterrupted)值为false,表示返回线程的中断状态,不会清理线程的中断状态。
4、因为3条的原因,如果线程中断,连续调用interrupted(),第一次返回true,第二次返回false。之后在调用会一直是false;如果线程没有中断效果与isInterrupted() 一样。
而isInterrupted()不管线程是否中断 都只会返回当前线程的中断状态,多次调用都会返回同一个结果。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值