interrupt方法
interrupt字面上是中斷的意思,但在Java裡Thread.interrupt()方法實際上透過某種方式通知線程,並不會直接中止該線程。具體做什麼事情由寫程式碼的人決定,通常我們會中止該線程。
如果執行緒在呼叫Object類別的wait()、wait(long)或wait(long, int)方法,或該類別的join() 、join(long) 、join(long, int) 、sleep(long) 或sleep (long, int) 方法過程中受阻,則其中斷狀態將被清除,它也會收到一個InterruptedException。
如果該執行緒在可中斷的通道(java.nio.channels.InterruptibleChannel)上的I/O 操作中受阻,則該通道將被關閉,該執行緒的中斷狀態將被設定並且該執行緒將收到一個ClosedByInterruptException。
如果該線程在一個Selector (java.nio.channels.Selector) 中受阻,則該線程的中斷狀態將被設置,它將立即從選擇操作返回,並可能帶有非零值,就好像調用了選擇器的wakeup 方法一樣。
如果先前的條件都沒有儲存,則該執行緒的中斷狀態將會被設定。
中斷一個不處於活動狀態的執行緒不需要任何作用。
檢測中斷
如何檢測中斷決定於線程所做的事情。
如果執行緒呼叫可以拋出InterruptException的方法,則擷取InterruptException,然後在catch區塊中處理(通常是退出run方法中斷執行緒)
如果呼叫其它方法,則可以在空閒時檢查Thread.interrupted以判斷是否收到中斷訊號,確認收到中斷訊號後進行處理。可以拋出一個InterruptException從而和前一種處理方法保持一致
中斷狀態
線程的中斷機制是使用中斷狀態這個內部標誌來實現的。中斷狀態在呼叫執行緒的interrupt()方法時被設定(參考上面的interrupt方法說明)。
有兩種方法可以取得線程的中斷狀態:
呼叫靜態方法Thread.interrupted(),該方法除了傳回目前執行緒的中斷狀態外,還會清除目前執行緒的中斷狀態。換句話說,如果連續兩次呼叫該方法,則第二次呼叫將傳回false(在第一次呼叫已清除了其中斷狀態之後,且第二次呼叫檢驗完中斷狀態前,當前執行緒再次中斷的情況除外)。
呼叫指定執行緒的isInterrupted()方法,該方法只會傳回指定執行緒的中斷狀態而不影響該執行緒的中斷狀態。
有兩種方法可以清除線程的中斷狀態:
如上所述,呼叫Thread.interrupted()
呼叫該執行緒的interrupt()方法引發InterruptedException的時候同時就已經清除了所在執行緒的中斷狀態,包括Object類別的wait()、wait(long)或wait(long, int)方法,或執行緒的join() 、join(long) 、join(long, int) 、sleep(long) 或sleep(long, int) 方法