早期 Java 提供 stop()、suspend()、resume() 等強制控制方法,但因導致資料不一致、死結等嚴重問題已被淘汰。現代標準模式採用 interrupt() 中斷協作 + volatile 旗標 + wait/notify 機制實現優雅控制。
public class threadCtrl {
public static void main(String[] main) {
new threadCtrl();
}
threadCtrl() {
try {
Thread tm = Thread.currentThread(); // 主執行緒
threadchild td = new threadchild();
td.start();
tm.sleep(500);
System.out.println("interrupt child thread");
td.interrupt(); // 1. 中斷:設置中斷旗標
System.out.println("let child thread wait!");
// td.wait(); // 錯誤:wait() 需在 synchronized 區塊內
// td.suspend(); // 已淘汰
tm.sleep(1000);
System.out.println("let child thread working");
td.fauxresume(); // 2. 自訂恢復:旗標 + notify
// td.resume(); // 已淘汰
tm.sleep(1000);
td.runflag = false; // 3. 旗標停止:優雅結束
System.out.println("main over..............");
} catch (InterruptedException ie) { System.out.println("inter main::" + ie); }
catch (Exception e) { System.out.println("main::" + e); }
}
}
// 被控執行緒類別
class threadchild extends Thread {
boolean runflag = true; // 執行旗標
boolean suspended = true; // 暫停旗標
threadchild() {}
// 自訂恢復方法:旗標 + notify
public synchronized void fauxresume() {
suspended = false;
notify(); // 喚醒在 wait() 中的執行緒
}
public void run() {
while (runflag) {
System.out.println("I am working..............");
try {
sleep(1000);
} catch (InterruptedException e) {
System.out.println("sleep::" + e);
}
synchronized (this) {
try {
if (suspended)
wait(); // 釋放鎖進入等待集
} catch (InterruptedException e) {
System.out.println("wait::" + e);
}
}
}
System.out.println("thread over...........");
}
}
| 控制需求 | 淘汰方法 | 現代標準模式 | 核心原理 |
|---|---|---|---|
| 中斷執行緒 | stop() | interrupt() | 設置中斷旗標,阻塞方法拋出 InterruptedException |
| 暫停執行緒 | suspend() | volatile 旗標 + wait() | 釋放鎖進入等待集,不持有鎖 |
| 恢復執行緒 | resume() | notify()/notifyAll() | 喚醒等待集中執行緒 |
| 停止執行緒 | stop() | volatile 旗標 + interrupt() | 迴圈檢查旗標,主動退出 run() |
sleep()、wait() 等阻塞方法會拋出 InterruptedException 並清除旗標wait() 釋放鎖,notify() 喚醒一個等待執行緒runflag、suspended 確保跨執行緒可見性notify()public class GracefulThread extends Thread {
private volatile boolean running = true;
public void run() {
while (running && !Thread.currentThread().isInterrupted()) {
try {
// 業務邏輯
Thread.sleep(1000);
} catch (InterruptedException e) {
// 休眠被中斷,檢查旗標決定是否退出
Thread.currentThread().interrupt(); // 重置中斷旗標(可選)
}
}
// 清理資源
}
public void shutdown() {
running = false;
interrupt(); // 輔助中斷阻塞操作
}
}
td.wait() 呼叫於非同步區塊 → IllegalMonitorStateExceptionInterruptedException 導致中斷信號丟失suspend()/resume() 造成死結volatile 導致可見性問題ExecutorService 管理執行緒生命週期(shutdown()、shutdownNow())Thread.currentThread().isInterrupted()finally 或 try-with-resourcesThread 實例,改用高階並發工具理解執行緒控制的演進歷程,才能寫出健壯、可維護的並發程式。