在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