中斷狀態
每一個執行緒都有一個boolean屬性,表示中斷狀態,初始值為false。
中斷執行緒:Thread.interrupt()
正常情況下,只是將執行緒的中斷狀態變為true
。執行緒中可以通過輪詢中斷狀態,做出相應的處理。
如果執行緒在阻塞狀態下,執行緒將退出阻塞且中斷狀態將被清除
(即為false),且會丟擲InterruptException。
(IO操作忽略)
查詢中斷狀態
(1)isInterrupted(),返回當前的中斷狀態,不會改變中斷狀態。
(2)static interrupted(),返回當前中斷狀態,且會清除中斷狀態。(即第二次呼叫將返回 false)
處理InterruptedException
(1)繼續丟擲。
如果丟擲InterruptedException意味著是一個阻塞方法,那麼呼叫一個阻塞方法則意味著呼叫者也是一個阻塞方法,應該有某種策略來處理InterruptedException。
(2)捕獲InterruptedException,執行清理
,再重新丟擲InterruptedException。
(3)再次呼叫interrupt()。
當由Runnable定義的任務呼叫一個可中斷的方法時,在這種情況下,不能重新丟擲InterruptedException,因為Runnable介面的run方法不允許丟擲異常。
當一個阻塞方法檢測到中斷並丟擲InterruptedException但是不能重新丟擲它,那麼應該保留中斷髮生的證據,以便呼叫棧中更高層的程式碼能知道中斷,並對中斷做出響應
,該任務可以通過呼叫interrupt()以重新中斷當前執行緒來完成。
public void run() {
try {
while (true) {
Task task = queue.take(10, TimeUnit.SECONDS);
task.execute();
}
}
catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
}
中斷一個不支援中斷的類
如一個IO類會阻塞執行緒,但不支援中斷。則可以寫一個新IO類,繼承Thread類,重寫interrupt方法,在interrupt中關閉IO,最後呼叫super.interrupt();
待決中斷
在進入阻塞前被中斷,被稱為待決中斷。
在呼叫阻塞方法時,會立刻丟擲InterruptException。