早期 Java 嘗試提供搶佔式中斷(Thread.stop、suspend、resume),但因易導致資料不一致、死鎖等嚴重問題已被棄用。現代 Java 採用協作式中斷:中斷只是一個請求,被中斷的執行緒自行決定如何響應。
JVM 為每個執行緒維護一個內部 中斷標記(boolean 型)。應用程式無法直接存取,需透過 Thread 提供的三個方法操作:
interrupt():設定中斷標記為 true。isInterrupted():查詢指定執行緒的中斷標記,不清除。static interrupted():查詢當前執行緒中斷標記,並清除標記。isInterrupted 為 native 方法,由 JVM 底層實現,確保跨平台一致性。
當執行緒處於 wait()、sleep()、join() 等阻塞狀態時,若收到中斷請求:
InterruptedException。此時應捕獲異常並執行清理或退出邏輯:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// 恢復中斷標記供上層檢查
Thread.currentThread().interrupt();
// 執行清理並退出
return;
}
以下操作不會自動拋出 InterruptedException,需替代方案:
| 場景 | 替代中斷方案 |
|---|---|
傳統 I/O (InputStream.read) | 關閉 Socket/Stream,觸發 SocketException |
NIO Selector (Selector.select) | 呼叫 wakeup(),觸發 ClosedSelectorException |
內建鎖 (synchronized) | 改用 Lock.lockInterruptibly() |