Thread.interrupt() 不會強制終止執行緒,而是發送中斷請求(設定內部中斷標記)。具體響應行為由目標執行緒決定,常見模式為拋出異常或檢查標記後退出。
| 執行緒狀態 | 中斷標記 | 拋出異常 | 說明 |
|---|---|---|---|
| 正常運行 | 設為 true | 否 | 需主動檢查 isInterrupted() |
| Object.wait() / Thread.sleep() / Thread.join() | 清除 | InterruptedException | 阻塞方法捕獲中斷並拋出異常 |
| InterruptibleChannel I/O | 設為 true | ClosedByInterruptException | 通道被關閉 |
| Selector.select() | 設為 true | 無(立即返回) | 需檢查返回值或 wakeup() |
| 非活躍執行緒 | 無影響 | 否 | 中斷已終止執行緒無效果 |
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 恢復標記
return; // 退出 run()
}
while (!Thread.currentThread().isInterrupted()) {
doWork();
}
// 或使用靜態方法(會清除標記)
while (!Thread.interrupted()) {
doWork();
}
注意:Thread.interrupted() 會清除當前執行緒中斷標記,連續呼叫第二次將回傳 false;isInterrupted() 僅查詢不清除。
interrupt()。Thread.interrupted()。thread.isInterrupted()。InterruptedException 時自動清除。Thread.interrupted() 時清除。// 錯誤示範
try { Thread.sleep(1000); } catch (InterruptedException e) { /* 什麼都不做 */ }
try { Thread.sleep(1000); }
catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 關鍵:恢復中斷狀態
throw new RuntimeException("執行緒被中斷", e);
}
掌握 interrupt() 的語義、中斷標記的生命週期、阻塞方法的差異響應,是編寫健壯多執行緒程式的基石。遵循「不吞沒中斷、正確傳播、使用框架取消 API」三原則,可避免多數併發 Bug。