看到标题上那三个兄弟了吗,看起来跟孪生兄弟一样,傻傻分不清楚。
很多人可能都知道这些方法,但是又不太能分清,所以给大家带来这篇文章,带大家一起区分一下这三个方法。
首先这三个方法都是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()方法并不会打断线程的运行,但是透过这个方法名我们也可以知道,这个方法肯定和打断线程有关,至于是怎么打断线程的,请听下回分解。
喜欢文章的,扫码关注微信公众号