1、中断
中断可以理解为线程的一个标识位属性,它表示一个运行中的线程是否被其他线程进行了中断操作。这就好比其它线程对该线程打了声招呼,其它线程通过调用该线程的interrupt()方法对其进行中断操作。
中断是一种协作机制。当一个线程中断另一个线程时,被中断的线程不一定要立即停止正在做的事情。相反,中断是礼貌地请求另一个线程在它愿意并且方便的时候停止它正在做的事情。
interrupted()
interrupted()方法的声明为
public static boolean interrupted();
其作用是测试当前线程是否已经中断。
interrupted()方法的实现为
public static boolean interrupted() {return currentThread().isInterrupted(true);
}
interrupted()方法调用了currentThread()方法,来返回正在执行该代码段的线程,然后调用该线程的isInterrupted(boolean ClearInterrupted)方法。其中,ClearInterrupted参数为true。
private native boolean isInterrupted(boolean ClearInterrupted);
该方法用来测试线程是否已经中断,同时,ClearInterrupted参数可以用来控制是否清除中断标志。
isInterrupted()
isInterrupted()方法的声明为
public boolean isInterrupted();
其作用是测试线程是否已经中断。
isInterrupted()方法的实现为
public boolean isInterrupted() {return isInterrupted(false);
}
isInterrupted()方法同样调用了线程的isInterrupted(boolean ClearInterrupted)方法来测试线程是否已经中断。其中,ClearInterrupted参数为false。
interrupted()方法与isInterrupted()方法的不同
1、interrupted()方法为Thread类的static方法,而isInterrupted()方法不是;
2、interrupted()方法用来测试正在运行当前代码线程的中断状态,isInterrupted()方法用来测试调用该方法的线程的中断状态;
3、interrupted()方法会重置线程的中断标志,而isInterrupted()方法不会重置。
2、InterruptedException
线程的中断状态初始时为false,当另一个线程通过调用Thread.interrupt()中断一个线程时,会出现以下两种情况之一。
1、如果那个线程在执行一个低级可中断的阻塞方法,例如 Thread.sleep()、 Thread.join() 或 Object.wait(),那么它将取消阻塞并抛出InterruptedException。在这些方法抛出InterruptedException异常之前,jvm会先将该线程的中断标志位清除,捕获异常后调用isInterrupted()方法将会返回false;
2、否则,interrupt()只是设置线程的中断状态。在被中断线程中运行的代码以后可以轮询中断状态,看看它是否被请求停止正在做的事情。
处理InterruptedException
1、可以捕捉InterruptedException异常,执行一些清理工作,然后抛出异常。
2、有时候抛出InterruptedException并不合适,例如当由Runnable定义的任务调用一个可中断的方法时,就是如此。在这种情况下,不能重新抛出InterruptedException异常,但是不要什么都不做而吞没异常,比较提倡的做法是保留中断发生的证据,以便调用栈中更高层的代码能知道中断,并对中断作出响应。如下所示:
public class Task implements Runnable {@Overridepublic void run() { try {Thread.sleep(3000);} catch (InterruptedException e) { // 重置中断标志Thread.currentThread().interrupt();}}
}
参考资料
方腾飞:《Java并发编程的艺术》
高洪岩:《Java多线程编程核心技术》