解析 Thread 中三种跟线程中断有关的方法
时间:2018年10月3日
1. interrupt()
interrupt() 这个方法是将当前线程的中断状态为 true,即调用 isInterrupted() 将返回 true。
其具体实现如下:
public void interrupt() {
// 只有自己才能够中断自己
// checkAccess() 这方法会抛出 SecurityException
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();
}
下面来看看例子:
public class InterruptedTheadTest {
public static void main(String[] args) {
Thread.currentThread().interrupt();
System.out.println("the current thread has been interrupted!");
}
}
结果输出:
the current thread has been interrupted!
结果与单独打印上面这句话一样。为什么不会抛出中断异常呢?
那这个方法到底该怎么用呢?实际上,这个方法是针对于阻塞的线程的。什么意思呢?就是当 处于阻塞的线程 调用 interrupt() 方法,将会抛出 InterruptException 异常。
下面让我们来稍微修改一下上面的代码:
public class InterruptedTheadTest {
public static void main(String[] args) {
Thread.currentThread().interrupt();
try {
Thread.currentThread().sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("the current thread has been interrupted!");
}
}
}
结果输出:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.wfms.concurrency.TestInterruptedThead.main(TestInterruptedThead.java:8)
the current thread has been interrupted!
2. isInterrupted()
直接来看源码:
public boolean isInterrupted() {
return isInterrupted(false);
}
/**
* @param CleanInterrupted,true 返回当前线程的中断状态,并清除其中断状态
* @param CleanInterrupted,false 返回当前线程的中断状态,不清除其中断状态
*/
private native boolean isInterrupted(boolean ClearInterrupted);
isInterrupted()
内部调用了 isInterrupted(false)
,这个方法是测试当前线程的中断状态。
-
true,说明当前线程已经被标记被中断状态,再这之后如果调用 wait()、sleep()、join() 这些方法将会抛出
InterruptedException
。 -
false,说明当前线程未被阻塞。
3. interrupted()
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
前面我们已经介绍过 isInterrupted(boolean) 这个方法,可知 interrupted()
这个方法返回当前线程的中断状态之后,再将其中断状态清除掉。
下面来演示对比 isInterrupted() 和 interrupted() 这两个方法的区别:
public class InterruptedTheadTest {
public static void main(String[] args) {
compareIsInterruptedAndInterrupted();
}
public static void compareIsInterruptedAndInterrupted() {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
Thread.currentThread().interrupt();
boolean isInterrupted = Thread.currentThread().isInterrupted();
System.out.println("t1: before call isInterruped: " + isInterrupted);
isInterrupted = Thread.currentThread().isInterrupted();
System.out.println("t1: after call isInterrupted: " + isInterrupted);
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
Thread.currentThread().interrupt();
boolean isInterrupted = Thread.currentThread().interrupted();
System.out.println("t2: before call interrupted: " + isInterrupted);
isInterrupted = Thread.currentThread().interrupted();
System.out.println("t2: after call interrupted: " + isInterrupted);
}
});
t1.start();
t2.start();
}
}
结果输出:
t1: before call isInterruped: true
t2: before call interrupted: true
t1: after call isInterrupted: true
t2: after call interrupted: false
4. 总结
- interrupt(),将当前线程的中断状态设置为 true。
- isInterrupted(),返回当前线程的中断状态(不清除其中断状态)。
- interrupted(),返回当前线程的中断状态并且清除其中断状态。