線程池生命週期包括:html
轉換成TIDYING狀態的線程會運行terminated方法。執行完terminated()方法以後,全部等待在awaitTermination()就會返回。
轉換過程爲:java
線程池是空的即有效線程數是0
若是代碼可以在某個操做正常徹底以前置入「完成」狀態,那麼這個操做就稱爲可取消的。java中提供了協做式機制,使請求取消的任務和代碼遵循一種協商好的協議。linux
線程中斷就是一種協做機制。它並不會真正的中斷一個正在運行的線程,而只是發出中斷請求,而後由線程在下一個合適的時刻中斷本身。
Thread中的中斷方法包括安全
public void interrupt() { if (this != Thread.currentThread()) checkAccess();//非當前線程有可能拋出SecurityException synchronized (blockerLock) { //用於執行可終端的IO操做對應的方法 Interruptible b = blocker; if (b != null) { //僅設置終端標記 interrupt0(); //執行實現了Interruptible接口的防範 b.interrupt(this); return; } } //僅設置終端標記 interrupt0(); }
調用它根據線程的不一樣場景,有不一樣的結果oracle
若是線程阻塞的是一個能夠中斷的channel,那麼channel會被關閉,同時線程會收到java.nio.channels.ClosedByInterruptException,而且會設置中斷標誌異步
//AbstractInterruptibleChannel中: protected final void begin() { if (interruptor == null) { interruptor = new Interruptible() { public void interrupt(Thread target) { synchronized (closeLock) { if (!open) return; open = false; interrupted = target; try { //關閉channel AbstractInterruptibleChannel.this.implCloseChannel(); } catch (IOException x) { } } }}; } blockedOn(interruptor); Thread me = Thread.currentThread(); if (me.isInterrupted()) interruptor.interrupt(me); }
若是線程阻塞在Selector,執行它的 wakeup方法,於是selector會當即返回,同時會設置中斷標誌ide
//AbstractSelector中: protected final void begin() { if (interruptor == null) { interruptor = new Interruptible() { public void interrupt(Thread ignore) { //執行wakeup,Selector當即返回 AbstractSelector.this.wakeup(); }}; } AbstractInterruptibleChannel.blockedOn(interruptor); Thread me = Thread.currentThread(); if (me.isInterrupted()) interruptor.interrupt(me); }
能夠看出調用interrupt並不意味着當即中止目標線程正在進行的工做,而只是傳遞了請求中斷的消息ui
清除當前線程的中斷狀態,並返回以前的值。它實際執行的就是當前線程的isInterrupted(true)this
public static boolean interrupted() { return currentThread().isInterrupted(true); }
假設當前線程是中斷的,此時調用會返回true,若是在下次調用以前沒有中斷,此時調用會返回false
返回目標線程的中斷狀態,只有線程狀態是中斷纔會返回true,其它時候返回falsespa
public boolean isInterrupted() { return isInterrupted(false); }
能夠看到interrupted和isInterrupted 調用的都是isInterrupted方法,只不過參數不同。它的參數實際表明的是是否要清除中斷標記,爲true也就清除,在java中的定義以下
private native boolean isInterrupted(boolean ClearInterrupted);
參考linux上的實現爲 ``` bool os::is_interrupted(Thread* thread, bool clear_interrupted) { assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer"); OSThread* osthread = thread->osthread(); bool interrupted = osthread->interrupted(); if (interrupted && clear_interrupted) { osthread->set_interrupted(false); //若是中斷了,而且要清除中斷標記,就改變終端標記 // consider thread->_SleepEvent->reset() ... optional optimization } return interrupted; } ```
通常策略以下
並不是全部的可阻塞方法或者阻塞機制都能響應中斷,中止線程的方法相似於中斷
Thread.stop自己是不安全的。中止一個線程會釋放它全部的鎖的監視器,若是有任何一個受這些監視器保護的對象出現了狀態不一致,其它的線程也會以不一致的狀態查看這個對象,其它線程在這個對象上的任何操做都是沒法預料的
爲何廢棄了Thread.stop
應用程序準備退出時,這些服務所擁有的線程也應該結束。
ExecutorService提供了兩種方法:shutdown和shutdownNow