暴力終止,導致鎖釋放不確定、對象損壞、數據不一致。嚴禁使用。
public class Worker implements Runnable {
private volatile boolean running = true; // 保證可見性
public void shutdown() { running = false; }
@Override
public void run() {
while (running) {
// 1. 執行任務單元
doTask();
// 2. 可選:檢查標誌位 (長任務中插入檢查點)
}
cleanup(); // 釋放資源
}
}
優點:簡單、可控、線程自然退出 run() 執行 finally 塊釋放資源。
缺點:無法中斷阻塞操作 (sleep/wait/join/IO/鎖)。
public class InterruptibleWorker implements Runnable {
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) { // 檢查中斷狀態
// 非阻塞任務
doTask();
// 或調用可中斷阻塞方法
Thread.sleep(1000); // 會拋 InterruptedException
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 重置標誌 (良好習慣)
} finally {
cleanup();
}
}
}
// 外部調用
workerThread.interrupt(); // 設置中斷標誌
| 場景 | interrupt() 效果 | 中斷狀態 |
|---|---|---|
| 線程運行中 (非阻塞) | 僅設置標誌位 | true (需自行檢查 isInterrupted()) |
| 線程阻塞於 sleep/wait/join | 拋出 InterruptedException | 自動清除 (為 false) |
| 線程阻塞於 IO (Channel) | 關閉 Channel,拋 ClosedByInterruptException | true |
| 線程阻塞於 Lock.lock() | 不響應 (ReentrantLock 不可中斷) | false |
| 線程阻塞於 Lock.lockInterruptibly() | 拋 InterruptedException | 清除 |
public class RobustWorker implements Runnable {
private volatile boolean shutdown = false; // 業務級標誌
@Override
public void run() {
try {
while (!shutdown && !Thread.currentThread().isInterrupted()) {
// 1. 可中斷阻塞操作優先
blockingQueue.take(); // 可中斷
// 2. 非阻塞任務 + 定期檢查
processBatch();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 傳遞中斷
} finally {
// 3. 統一清理
releaseResources();
}
}
public void stop() {
shutdown = true; // 業務標誌
thread.interrupt(); // 打破阻塞
}
}
volatile boolean 即可。interrupt()。InterruptedException 向上傳遞,不吞噬。