如何区分interrupt()、interrupted()、isInterrupted()

看到标题上那三个兄弟了吗,看起来跟孪生兄弟一样,傻傻分不清楚。

很多人可能都知道这些方法,但是又不太能分清,所以给大家带来这篇文章,带大家一起区分一下这三个方法。

首先这三个方法都是Thread类的方法,按照惯例,介绍方法,先看源码

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();
}

private native void interrupt0();

interrupt()方法是Thread类的一个方法,源码注释有点多,就不贴在这里了。

interrupt()方法会调用一个native方法interrupt0(),去为指定线程设置一个Interrupting状态,字面上是“打断”的意思。

但是我们要知道的是,指定线程调用interrupt()方法之后,对于线程的执行不会产生任何的变化,而仅仅是为指定线程设置了一个Interrupting状态。

既然是设置了一个状态,那么设置这个状态的作用是什么呢?

这就到了下面两个方法登场的时候了。

interrupted()、isInterrupted()

    /**
     * Tests whether the current thread has been interrupted.  The
     * <i>interrupted status</i> of the thread is cleared by this method.  In
     * other words, if this method were to be called twice in succession, the
     * second call would return false (unless the current thread were
     * interrupted again, after the first call had cleared its interrupted
     * status and before the second call had examined it).
     */
    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }

    /**
     * Tests whether this thread has been interrupted.  The <i>interrupted
     * status</i> of the thread is unaffected by this method.
     */
    public boolean isInterrupted() {
        return isInterrupted(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);

相信贴出这三段源码之后,大家对这两个方法也就了解的差不多了,毕竟注释写的那么清晰(代码注释的重要性再强调一遍)。

首先通过注释我们知道这两个方法都是去判断线程的“打断”状态,返回一个布尔值,也就是说是否调用了interrupt()方法。

我们发现interrupted()方法是Thread类的一个静态方法,这是一个基于类的方法,而不是基于对象,所以这个方法检查的是当前线程的“打断”状态,而不能去检查指定线程;而isInterrupted()方法不是一个静态方法,所以isInterrupted()方法可以用来检查任意指定线程的的“打断”状态。

我们发现这两个方法都调用了一个native方法isInterrupted(boolean ClearInterrupted),只不过参数不同。通过注释我们可以知道,interrupted()调用了之后会重置“打断”状态,而interrupted()方法则不会。

什么叫重置“打断”状态呢,我们用下面一段代码来解释一下。

    @Test
    public void testInterrupted(){
        boolean b1 = Thread.interrupted();  //false
        Thread.currentThread().interrupt();
        boolean b2 = Thread.interrupted();  //true
        boolean b3 = Thread.interrupted();  //false
    }

    @Test
    public void testIsInterrupted(){
        boolean b4 = Thread.currentThread().isInterrupted(); //false
        Thread.currentThread().interrupt();
        boolean b5 = Thread.currentThread().isInterrupted(); //true
        boolean b6 = Thread.currentThread().isInterrupted(); //true
    }
  • b1=false 当前线程没有调用interrupt()方法,所以interrupted状态为false
  • b2=true 当前线程调用了interrupt()方法,所以interrupted状态为true
  • b3=false 在b2那一行Thread.interrupted()方法调用结束后,会重置当前线程的interrupted状态为false
  • b4=false 同b1
  • b5=true 同b2
  • b6=true b5哪一行Thread.currentThread().isInterrupted()方法调用结束后,并不会重置当前线程的interrupted状态,所以b6还是true

到这里,大家应该已经很清楚这三个方法的作用了:
- interrupt()会为指定线程设置一个interrupted状态
- interrupted()会判断当前线程的interrupted状态,并且会重置该状态
- isInterrupted()会判断指定线程的interrupted状态

到这里大家可能还会有些小疑问
- 1.为什么interrupted()要设置成静态方法?
- 2.虽然已经知道这三个方法的作用了,那么我们到底需要它们吗?

我先来谈一下对第一个问题的理解。既然isInterrupted()方法没有被静态修饰,那么我们就从这两个方法的区别去分析这个static关键字存在的意义。

interrupted()方法需要去重置线程的interrupted状态,也就是需要去修改线程,而isInterrupted()只是查询现成的interrupted状态,不会对线程进行修改。

这应该就是interrupted()方法需要被静态修饰的原因,否则的话,当前线程去调用指定线程的interrupted()方法,还需要去修改指定线程,调用指定线程的native方法,显得有些麻烦了,所以就给interrupted()加了个static关键字。

当然了这是我自己的理解,可能不太全面,大家看一下乐呵乐呵就好,不要较真。

至于第二个问题,这三个方法的作用。虽然上面描述了调用interrupt()方法并不会打断线程的运行,但是透过这个方法名我们也可以知道,这个方法肯定和打断线程有关,至于是怎么打断线程的,请听下回分解。

喜欢文章的,扫码关注微信公众号
扫码关注

猜你喜欢

转载自blog.csdn.net/Leon_cx/article/details/81160571
今日推荐