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

Java Thread 多線程核心原理全景解析:生命周期、創建方式、狀態轉換與停止模式

     編輯:Java 相關知識

線程生命周期:五大狀態轉換圖


NEW (新建) → start() → RUNNABLE (就緒) ⇄ RUNNING (運行)
                    ↑              ↓
                    │         BLOCKED (阻塞)
                    │    (同步鎖/IO/sleep/wait)
                    └──────────────┘
                              ↓
                          TERMINATED (終止)
  • NEW:new Thread(),僅分配資源
  • RUNNABLE:start() 後,等待 CPU 調度 (含就緒+運行)
  • BLOCKED:三種子類型
    1. 同步阻塞:爭搶 synchronized 鎖
    2. 等待阻塞:wait()、join() (無超時)
    3. 定時阻塞:sleep()、wait(timeout)、join(timeout)、IO 操作
  • TERMINATED:run() 正常返回或拋出未捕獲異常

三種創建線程的方式對比

方式核心代碼優點缺點
繼承 Threadclass MyThread extends Thread { run(){} }簡單、可直接 this.getName()單繼承限制、邏輯與控制耦合
實現 Runnableclass MyTask implements Runnable { run(){} } new Thread(new MyTask()).start()邏輯分離、可共享任務實例、支持線程池需包裝 Thread 獲取線程信息
Callable + FutureTasknew Thread(new FutureTask<>(() -> { return result; })).start()有返回值、可拋受檢異常、支持取消/超時語法稍繁瑣

關鍵源碼洞察:Thread 與 Runnable 的關係


// Thread 實現了 Runnable
public class Thread implements Runnable {
    private Runnable target;
    public Thread(Runnable target) { this.target = target; }
    @Override public void run() { if (target != null) target.run(); }
}
// 多態陷阱:若子類重寫 run(),target.run() 不會被調用!
class MyThread extends Thread {
    public MyThread(Runnable r) { super(r); }
    @Override public void run() { System.out.println("子類 run"); } // 覆蓋父類邏輯
}
new Thread(new MyThread(() -> System.out.println("Lambda"))).start();
// 輸出: "子類 run" ———— Lambda 丟失!

教訓:繼承 Thread 時不要同時傳 Runnable,或調用 super.run()。

線程停止的正確姿勢

❌ 錯誤方式

  • Thread.stop() / suspend() / resume():已棄用,導致鎖強制釋放、數據不一致
  • interrupt() 後不檢查狀態:線程繼續執行

✅ 標準模式:volatile 標誌位 + interrupt 輔助


class Worker implements Runnable {
    private volatile boolean running = true;
    public void shutdown() { running = false; }
    @Override public void run() {
        while (running && !Thread.currentThread().isInterrupted()) {
            try {
                // 業務邏輯
                Thread.sleep(100); // 可響應 interrupt
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // 重置標誌
                break; // 或拋出
            }
        }
        // 清理資源
    }
}
// 使用
Worker w = new Worker();
Thread t = new Thread(w); t.start();
// ... 後續停止
w.shutdown(); t.interrupt(); // 雙重保障

yield()、join()、sleep() 精準區別

方法釋放鎖狀態轉換典型用途
yield()否RUNNING → RUNNABLE禮讓 CPU,同優先級輪轉
sleep(ms)否RUNNING → TIMED_WAITING定時任務、限流
join()否RUNNING → WAITING/TIMED_WAITING等待另一線程結束
wait()是RUNNING → WAITING條件變量協作 (需在 synchronized 中)

守護線程

  • setDaemon(true) 必須在 start() 前調用
  • JVM 退出時不等待守護線程 (如 GC、JIT 編譯線程)
  • 用戶線程全部結束 → JVM 關閉,守護線程被強制終止

總結

掌握 Thread 的生命周期狀態機、三種創建模式的本質區別、安全停止模式、核心輔助方法語義,是 Java 併發編程的入門基石。實戰中:優先 Runnable + 線程池、volatile 標誌位停止、避免直接操作 Thread 實例,複雜協作轉用 java.util.concurrent 組件。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved