线程中断
@see http://www.infoq.com/cn/articles/java-interrupt-mechanism
@see https://www.ibm.com/developerworks/cn/java/j-jtp05236.html
每个线程都有一个与之相关联的 Boolean 属性,用于表示线程的中断状态(interrupted status)。中断状态初始时为 false;当另一个线程通过调用 Thread.interrupt() 中断一个线程时,会出现以下两种情况之一:
1、如果那个线程在执行一个低级可中断阻塞方法,例如 Thread.sleep()、 Thread.join() 或 Object.wait(),那么它将取消阻塞并抛出 InterruptedException
2、否则, interrupt() 只是设置线程的中断状态。 在被中断线程中运行的代码以后可以轮询中断状态,看看它是否被请求停止正在做的事情。
Java中断机制是一种协作机制,也就是说通过中断并不能直接终止另一个线程,而需要被中断的线程自己处理中断。
中断状态可以通过 Thread.isInterrupted() 来读取,并且可以通过一个名为 Thread.interrupted() 的操作读取和清除。
interrupted
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
测试当前线程是否已经中断,线程的中断状态 由该方法清除。
换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。
isInterrupted
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
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
.
interrupt0(); // Just to set the interrupt flag
...
中断线程。仅仅是设置一个中断标志位。
处理中断
一般说来,当可能阻塞的方法声明中有抛出InterruptedException则暗示该方法是可中断的,如BlockingQueue#put、BlockingQueue#take、Object#wait、Thread#sleep等,
如果程序捕获到这些可中断的阻塞方法抛出的InterruptedException或检测到中断后,这些中断信息该如何处理?一般有以下两个通用原则:
1、如果遇到的是可中断的阻塞方法抛出InterruptedException,可以继续向方法调用栈的上层抛出该异常,如果是检测到中断,则可清除中断状态并抛出InterruptedException,使当前方法也成为一个可中断的方法。
2、若有时候不太方便在方法上抛出InterruptedException,比如要实现的某个接口中的方法签名上没有throws InterruptedException(如Runnable run 方法),这时就可以捕获可中断方法的InterruptedException,
并通过Thread.currentThread.interrupt()来重新设置中断状态。
网友评论