run() 方法執行完畢自然退出。Thread.stop()。interrupt() + 中斷狀態檢查。源碼註釋明確指出:
ThreadDeath 錯誤導致鎖非正常釋放,被保護的共享數據可能處於不一致狀態(如轉賬扣款成功但入賬失敗)。volatile boolean 標誌位或 interrupt() 通知線程自行退出。實例方法,設置目標線程的中斷狀態為 true。若線程處於阻塞狀態(sleep()、wait()、join()、I/O),將拋出 InterruptedException 並**清除中斷狀態**;否則僅設置標誌位。
靜態方法,檢查**當前線程**(調用線程)的中斷狀態,**並清除該狀態**。連續調用兩次第二次返回 false(除非再次被中斷)。
實例方法,檢查**該線程對象代表的線程**的中斷狀態,**不清除狀態**。
// Thread.java
public static boolean interrupted() {
return currentThread().isInterrupted(true); // true = 清除狀態
}
public boolean isInterrupted() {
return isInterrupted(false); // false = 不清除
}
private native boolean isInterrupted(boolean ClearInterrupted);
| 方法 | 屬於 | 檢查對象 | 清除狀態 | 典型用途 |
|---|---|---|---|---|
| interrupt() | 實例 | 目標線程 | 否(設置為 true) | 發起中斷請求 |
| interrupted() | 靜態 | 當前線程 | 是 | 在當前線程中輪詢/消費中斷 |
| isInterrupted() | 實例 | 指定線程 | 否 | 外部監控線程狀態 |
public class InterruptDemo {
static class Worker extends Thread {
@Override public void run() {
while (!Thread.currentThread().isInterrupted()) { // 檢查標誌位
try {
Thread.sleep(1000); // 阻塞點可響應中斷
} catch (InterruptedException e) {
// 睡眠被中斷,異常拋出時狀態已被清除
// 重新設置標誌位以便外層循環檢測
Thread.currentThread().interrupt();
break;
}
}
System.out.println("Worker 線程安全退出");
}
}
public static void main(String[] args) throws InterruptedException {
Worker w = new Worker();
w.start();
Thread.sleep(3000);
w.interrupt(); // 發起中斷
w.join();
System.out.println("主線程結束");
}
}
Thread.currentThread().interrupt())或拋出異常。Thread.currentThread().isInterrupted()。Future.cancel(true)、ExecutorService.shutdownNow() 內部封裝了中斷邏輯。