Java基础-线程中断

线程中断

@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()来重新设置中断状态。

你可能感兴趣的:(Java基础-线程中断)