引言
如果对 Java 中断没有一个全面的了解,可能会误以为被中断的线程将立马退出运行,但事实并非如此。
中断机制是如何工作的?捕获或检测到中断后,是抛出 InterruptedException 还是重设中断状态以及在方法中吞掉中断状态会有什么后果?
Thread.stop 与中断相比又有哪些异同?
什么情况下需要使用中断?
线程池中的异常如何处理?
中断处理的最佳实践?
线程中断基础知识
1、interrupt()
interrupt方法用于中断线程。调用该方法的线程的状态为将被置为"中断"状态。
注意:线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状态为并做处理。支持线程中断的方法(也就是线程中断后会抛出interruptedException的方法)就是在监视线程的中断状态,一旦线程的中断状态被置为“中断状态”,就会抛出中断异常。
2、interrupted() 和 isInterrupted()
首先看一下API中该方法的实现:public static boolean interrupted() { return currentThread().isInterrupted(true);}
该方法就是直接调用当前线程的isInterrupted(true)的方法。
然后再来看一下 API 中 isInterrupted 的实现:public boolean isInterrupted() {return isInterrupted(false);}
该方法却直接调用当前线程的isInterrupted(false)的方法。
因此这两个方法有两个主要区别:
interrupted 是作用于当前线程,isInterrupted 是作用于调用该方法的线程对象所对应的线程。(线程对象对应的线程不一定是当前运行的线程。例如我们可以在A线程中去调用B线程对象的isInterrupted方法。)
这两个方法最终都会调用同一个方法-----isInterrupted(Boolean 参数),只不过参数固定为一个是true,一个是false;
注意: isInterrupted(Boolean 参数) 是 isInterrupted() 的重载方法。
由于第二个区别主要体现在调用的方法的参数上,让我们来看一看这个参数是什么含义
先来看一看被调用的方法 isInterrupted(boolean arg)(Thread类中重载的方法)的定义:private native boolean isInterrupted(boolean ClearInterrupted);
原来这是一个本地方法,看不到源码。不过没关系,通过参数名ClearInterrupted我们就能知道,这个参数代表是否要清除状态位。
如果这个参数为true,说明返回线程的状态位后,要清掉原来的状态位(恢复成原来情况)。这个参数为false,就是直接返回线程的状态位。
这两个方法很好区分,只有当前线程才能清除自己的中断位(对应interrupted()方法)
验证例子public class Interrupt { public static void main(String[] args) throws Exception {
Thread t = new Thread(new Worker());
t.start();
Thread.sleep(200);
t.interrupt();
System.out.println("Main thread stopped."); }
public static class Worker implements Runnable { public void run() {
System.out.println("Worker started.");
try {
Thread.sleep(500); } catch (InterruptedException e) {
System.out.println("Worker IsInterrupted: " +
Thread.currentThread().isInterrupted()); }
System.out.println("Worker stopped."); } } }
内容很简答:主线程main启动了一个子线程Worker,然后让worker睡500ms,而main睡200ms,之后main调用worker线程的interrupt方法去中断worker,worker被中断后打印中断的状态。
下面是执行结果:Worker started.
Main thread stopped.
Worker IsInterrupted: false
Worker stopped.
Worker明明已经被中断,而isInterrupted()方法竟然返回了false,为什么呢?
InterruptedException 描述
在stackoverflow上搜索了一圈之后,发现有网友提到:可以查看抛出InterruptedException方法的JavaDoc(或源代码),于是我查看了Thread.sleep方法的文档,doc中是这样描述这个InterruptedException异常的:InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
结论:interrupt方法是用