public class SigleThread extends Thread {
@Override public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(i);
try { join(); } catch (InterruptedException e) { e.printStackTrace(); }
}
}
}
public class Test {
public static void main(String[] args) {
SigleThread sing = new SigleThread();
sing.start(); // 啟動 sing 執行緒
}
}
主控台輸出 0 後永久卡住 (死鎖)。
sing.start() 啟動新執行緒 (稱 **Thread-0**),執行 run()。run() 內部呼叫 join() → 實為 this.join(),此處 this 指向 **sigleThread 實例 (sing)**。Thread.join() 源碼邏輯:while (isAlive()) wait(0);sing (Thread-0) 正在執行 run(),故 isAlive() == true → **自己等待自己** → 永久阻塞。
Runnable sing = new SigleThread(); // 只是 Runnable 實例,非 Thread
Thread t = new Thread(sing); // 建立新 Thread 物件 (Thread-1)
t.start(); // 啟動 Thread-1,執行 sing.run()
run() 內的 this 仍指向 sing (Runnable 實例)。sing **從未被 start()**,故 sing.isAlive() == false。join() 發現 !isAlive() 直接返回,**不阻塞**,迴圈繼續輸出 1~4。| 寫法 | run() 中 this | isAlive() | join() 行為 |
|---|---|---|---|
Thread 子類 + start() | Thread 實例 (自己) | true (正在跑) | **自己等自己 → 死鎖** |
Runnable + new Thread(r).start() | Runnable 實例 (非執行緒) | false (未啟動) | 立即返回 → 正常 |
otherThread.join()。ExecutorService、CompletableFuture、CountDownLatch 等高層協作工具,避免手動管理 Thread 生命週期。