在了解InterruptedException异常以前应该了解如下的几个关于线程的一些基础知识。html
线程在必定的条件下会发生状态的改变,下面是线程的一些状态java
<center><img src="http://p9jfgo4wc.bkt.clouddn.com/thread.png"/></center>学习
而InterruptedException异常从字面意思上就是中断异常,那么什么是中断呢?学习中断以前咱们先了解一下具体什么是阻塞ui
线程阻塞一般是指一个线程在执行过程当中暂停,以等待某个条件的触发。而什么状况才会使得线程进入阻塞的状态呢?this
若是咱们有一个运行中的软件,例如是杀毒软件正在全盘查杀病毒,此时咱们不想让他杀毒,这时候点击取消,那么就是正在中断一个运行的线程。.net
每个线程都有一个boolean类型的标志,此标志意思是当前的请求是否请求中断,默认为false。当一个线程A调用了线程B的interrupt方法时,那么线程B的是否请求的中断标志变为true。而线程B能够调用方法检测到此标志的变化。线程
/** * @program: Test * @description: * @author: hu_pf@suixingpay.com * @create: 2018-07-31 15:43 **/ public class InterrupTest implements Runnable{ public void run(){ try { while (true) { Boolean a = Thread.currentThread().isInterrupted(); System.out.println("in run() - about to sleep for 20 seconds-------" + a); Thread.sleep(20000); System.out.println("in run() - woke up"); } } catch (InterruptedException e) { Thread.currentThread().interrupt();//若是不加上这一句,那么cd将会都是false,由于在捕捉到InterruptedException异常的时候就会自动的中断标志置为了false Boolean c=Thread.interrupted(); Boolean d=Thread.interrupted(); System.out.println("c="+c); System.out.println("d="+d); } } public static void main(String[] args) { InterrupTest si = new InterrupTest(); Thread t = new Thread(si); t.start(); //主线程休眠2秒,从而确保刚才启动的线程有机会执行一段时间 try { Thread.sleep(2000); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println("in main() - interrupting other thread"); //中断线程t t.interrupt(); System.out.println("in main() - leaving"); } }
打印的参数以下:日志
in run() - about to sleep for 20 seconds-------false in main() - interrupting other thread in main() - leaving c=true d=false
如今知道线程能够检测到自身的标志位的变化,可是他只是一个标志,若是线程自己不处理的话,那么程序仍是会执行下去,就比如,老师在学校叮嘱要好好学习,具体何时,如何好好学习仍是看自身。code
所以interrupt() 方法并不能当即中断线程,该方法仅仅告诉线程外部已经有中断请求,至因而否中断还取决于线程本身htm
简单的了解了什么是阻塞和中断之后,咱们就该了解碰到InterruptedException异常该如何处理了。
有时候阻塞的方法抛出InterruptedException异常并不合适,例如在Runnable中调用了可中断的方法,由于你的程序是实现了Runnable接口,而后在重写Runnable接口的run方法的时候,那么子类抛出的异常要小于等于父类的异常。而在Runnable中run方法是没有抛异常的。因此此时是不能抛出InterruptedException异常。若是此时你只是记录日志的话,那么就是一个不负责任的作法,由于在捕获InterruptedException异常的时候自动的将是否请求中断标志置为了false。至少在捕获了InterruptedException异常以后,若是你什么也不想作,那么就将标志从新置为true,以便栈中更高层的代码能知道中断,而且对中断做出响应。
捕获到InterruptedException异常后恢复中断状态
public class TaskRunner implements Runnable { private BlockingQueue<Task> queue; public TaskRunner(BlockingQueue<Task> queue) { this.queue = queue; } public void run() { try { while (true) { Task task = queue.take(10, TimeUnit.SECONDS); task.execute(); } } catch (InterruptedException e) { // Restore the interrupted status Thread.currentThread().interrupt(); } } }