詳解:執行緒中斷詳解
總結:
一、沒有任何語言方面的需求一個被中斷的執行緒應該終止,中斷一個執行緒只是為了引起該執行緒的注意,被中斷執行緒可以決定如何應對中斷,
二、對于處于sleep,join等操作的執行緒,如果被呼叫interrupt()后,會拋出InterruptedException,然后執行緒的中斷標志位會由true重置為false,因為執行緒為了處理例外已經重新處于就緒狀態,
三、不可中斷的操作,包括進入synchronized段以及Lock.lock(),inputSteam.read()等,呼叫interrupt()對于這幾個問題無效,因為它們都不拋出中斷例外,如果拿不到資源,它們會無限期阻塞下去,
對于Lock.lock(),可以改用Lock.lockInterruptibly(),可被中斷的加鎖操作,它可以拋出中斷例外,等同于等待時間無限長的Lock.tryLock(long time, TimeUnit unit),
對于inputStream等資源,有些(實作了interruptibleChannel介面)可以通過close()方法將資源關閉,對應的阻塞也會被放開,
首先,看看Thread類里的幾個方法:
| public static boolean interrupted | 測驗當前執行緒是否已經中斷,執行緒的中斷狀態 由該方法清除,換句話說,如果連續兩次呼叫該方法,則第二次呼叫將回傳 false, |
|
public boolean isInterrupted() |
測驗執行緒是否已經中斷,執行緒的中斷狀態 不受該方法的影響, |
|
public void interrupt() |
中斷執行緒, |
上面列出了與中斷有關的幾個方法及其行為,可以看到interrupt是中斷執行緒,如果不了解Java的中斷機制,這樣的一種解釋極容易造成誤解,認為呼叫了執行緒的interrupt方法就一定會中斷執行緒,
其實,Java的中斷是一種協作機制,也就是說呼叫執行緒物件的interrupt方法并不一定就中斷了正在運行的執行緒,它只是要求執行緒自己在合適的時機中斷自己,每個執行緒都有一個boolean的中斷狀態(這個狀態不在Thread的屬性上),interrupt方法僅僅只是將該狀態置為true,
比如對正常運行的執行緒呼叫interrupt()并不能終止他,只是改變了interrupt標示符,
一般說來,如果一個方法宣告拋出InterruptedException,表示該方法是可中斷的,比如wait,sleep,join,也就是說可中斷方法會對interrupt呼叫做出回應(例如sleep回應interrupt的操作包括清除中斷狀態,拋出InterruptedException),例外都是由可中斷方法自己拋出來的,并不是直接由interrupt方法直接引起的,
Object.wait, Thread.sleep方法,會不斷的輪詢監聽 interrupted 標志位,發現其設定為true后,會停止阻塞并拋出 InterruptedException例外,
--------------------------------------------------------------------------------------------------------------------------------------------------------------
看了以上的說明,對java中斷的使用肯定是會了,但我想知道的是阻塞了的執行緒是如何通過interuppt方法完成停止阻塞并拋出interruptedException的,這就要看Thread中native的interuppt0方法了,
總結:
NEW和TERMINATED對于中斷操作幾乎是屏蔽的,
RUNNABLE和BLOCKED類似,對于中斷操作只是設定中斷標志位并沒有強制終止執行緒,對于執行緒的終止權利依然在程式手中,
WAITING/TIMED_WAITING狀態下的執行緒對于中斷操作是敏感的,他們會拋出例外并清空中斷標志位,
參考:
并發之執行緒以及執行緒的中斷狀態
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/169000.html
標籤:其他
上一篇:Git操作常用的命令都在這里了。
