首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 執行緒調度實戰:join、守護執行緒與生命週期完整指南

     編輯:Java 相關知識

執行緒生命週期四大狀態

  1. 新建:new Thread(),未獲資源,非 alive。
  2. 可執行:呼叫 start(),進入排程佇列,等待 CPU。
  3. 阻塞/等待:sleep()、wait()、I/O 等待,釋放 CPU。
  4. 終止:run() 結束或異常中止,不可重啟。

執行緒生命週期圖

等待執行緒結束:join() vs isAlive()

方式一:isAlive() + sleep() 輪詢(不推薦)

t1.start();
while (t1.isAlive()) {
    Thread.sleep(100); // 主執行緒休眠
}
t2.start(); // t1 結束後再啟動 t2

缺點:忙碌等待、精度受 sleep 影響、程式碼冗長。

方式二:join() 方法(標準作法)

t1.start();
try {
    t1.join(); // 當前執行緒等待 t1 結束
} catch (InterruptedException e) {
    e.printStackTrace();
}
t2.start();
  • join()、join(long ms)、join(long ms, int ns) 支援超時。
  • 底層以 wait() 實作,被中斷會拋 InterruptedException。

守護執行緒:後台服務角色

  • setDaemon(true) 標記為守護執行緒(需在 start() 前呼叫)。
  • JVM 僅在所有使用者執行緒結束後才關閉,守護執行緒會被強制終止。
  • 典型用途:GC、記憶體監控、定時清理、日誌寫入等輔助任務。

範例:主程式結束自動停止守護執行緒

class DaemonTask extends Thread {
    public void run() {
        for (int i=0; i<100; i++) {
            System.out.println("Daemon running: " + i);
            try { Thread.sleep(200); } catch (InterruptedException e) {}
        }
    }
}

public class Demo {
    public static void main(String[] args) {
        DaemonTask dt = new DaemonTask();
        dt.setDaemon(true); // 設為守護執行緒
        dt.start();
        System.out.println("Main thread ends."); // 主執行緒結束,JVM 關閉,Daemon 立即停止
    }
}

yield() 與 sleep() 讓出 CPU

方法行為鎖狀態適用場景
yield()暫停目前執行緒,回到可執行狀態,不保證能讓同優先級執行緒執行持有鎖長時間計算中主動讓出 CPU
sleep(ms)進入阻塞狀態指定時間,不釋放鎖持有鎖定時輪詢、節流

注意:同步區塊中避免呼叫 yield(),否則持有鎖導致其他執行緒飢餓。

最佳實務彙整

  • 用 join() 等待執行緒,而非輪詢 isAlive()。
  • 輔助性背景任務設為 Daemon,避免阻塞 JVM 關閉。
  • 優先使用 ExecutorService(java.util.concurrent)管理執行緒池,手動管理 Thread 僅用於教學或極簡場景。
  • 避免在 run() 直接處理複雜邏輯,採用 Runnable/Callable 分離任務與執行機制。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved