在Core Java中有这样一句话:"没有任何语言方面的需求要求一个被中断的程序应该终止。中断一个线程只是为了引发该线程的注意,被中断线程能够决定如何应对中断 "
线程中断不会使线程当即退出,而是给线程发送一个通知,告知目标线程有人但愿你退出。至于目标线程接收到通知后如何处理,则彻底由目标线程自行决定。网络
静态方法Thread.interrupted()也是用来判断当前线程的中断状态,但同时会清除当前线程的中断标志位状态。ide
运行中的线程不会由于interrupt()而中断,由于它仅仅是一个信号(status)线程
public static void main(String[] intsmaze) throws InterruptedException { Thread t1=new Thread() { public void run() { while(true){ } } }; t1.start(); Thread.sleep(2000); t1.interrupt(); }
这个程序虽然对t1进程了中断,可是在t1中并无中断处理的逻辑,所以即便t1线程被置上了中断状态,可是这个中断不会发生任何做用。
若是但愿t1在中断后退出,必须为他增长相应的中断处理代码,以下code
public static void main(String[] intsmaze) throws InterruptedException { Thread t1=new Thread() { public void run() { while(true) { if(Thread.currentThread().isInterrupted())//判断当前线程是否中断。 { System.out.println("intsmaze Interrupt"); break; } } } }; t1.start(); Thread.sleep(2000); t1.interrupt(); }
public static native void sleep(long millis) throws InterruptedException;会抛出一个中断异常。当线程在休眠sleep时,若是被中断就会产生该异常,此时它会清楚中断标志,若是不加处理,那么在下一次循环开始时,就没法捕获这个中断。
若是注释掉catch中的Thread.currentThread().interrupt();咱们能够发现,程序一直运行,线程没有中止;反之放开该注释,则发现程序运行结束了。对象
public static void main(String[] intsmaze) throws InterruptedException { Thread t1=new Thread() { public void run() { while(true) { if(Thread.currentThread().isInterrupted()) { System.out.println("intsmaze Interrupt"); break; } try { Thread.sleep(6000); } catch (InterruptedException e) { System.out.println("Interrupt when intsmaze sleep"); Thread.currentThread().interrupt();//设置中断状态 } } } }; t1.start(); Thread.sleep(2000); t1.interrupt(); }
若是线程在等待锁,对线程对象调用interrupt()只是会设置线程的中断标志位,线程依然会处于BLOCKED状态,也就是说,interrupt()并不能使一个在等待锁的线程真正”中断”。经过前面的代码能够看到,中断是经过循环不判进行Thread.currentThread().isInterrupted()判断的。
在使用synchronized关键字获取锁的过程当中不响应中断请求,这是synchronized的局限性。若是想在等待获取锁的过程当中能响应中断,应该使用显式锁,Lock接口,它支持以响应中断的方式获取锁。接口
若是线程还没有启动(NEW),或者已经结束(TERMINATED),则调用interrupt()对它没有任何效果,中断标志位也不会被设置。好比说,如下代码的输出都是false。进程
若是线程在等待IO操做,尤为是网络IO,则会有一些特殊的处理。
若是IO通道是可中断的,即实现了InterruptibleChannel接口,则线程的中断标志位会被设置,同时,线程会收到异常ClosedByInterruptException。
若是线程阻塞于Selector调用,则线程的中断标志位会被设置,同时,阻塞的调用会当即返回。
咱们重点介绍另外一种状况,InputStream的read调用,该操做是不可中断的,若是流中没有数据,read会阻塞 (但线程状态依然是RUNNABLE),且不响应interrupt(),与synchronized相似,调用interrupt()只会设置线程的中断标志,而不会真正”中断”它,咱们看段代码。it
public class InterruptReadDemo { private static class A extends Thread { @Override public void run() { while(!Thread.currentThread().isInterrupted()){ try { System.out.println(System.in.read()); } catch (IOException e) { e.printStackTrace(); } } System.out.println("exit"); } } public static void main(String[] args) throws InterruptedException { A t = new A(); t.start(); Thread.sleep(100); t.interrupt(); } }
线程t启动后调用System.in.read()从标准输入读入一个字符,不要输入任何字符,咱们会看到,调用interrupt()不会中断read(),线程会一直运行。io