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

Java 多線程生命週期完整解析:六大狀態與關鍵 API

     編輯:Java 相關知識

線程六大狀態 (Thread.State 枚舉)

狀態描述觸發條件
NEW新建new Thread(),未調用 start()
RUNNABLE可運行調用 start(),等待 CPU 調度或正在執行
BLOCKED阻塞等待進入 synchronized 方法/塊,鎖被其他線程持有
WAITING無限等待Object.wait()、Thread.join()、LockSupport.park()
TIMED_WAITING限時等待Thread.sleep()、wait(timeout)、join(timeout)、parkNanos()
TERMINATED終止run() 正常返回或拋出未捕獲異常

狀態轉換圖 (核心路徑)

NEW --start()--> RUNNABLE <------- 時間片輪轉 / 鎖釋放 / 通知 / 超時 -------
  ↑                    ↑    ↓          ↓            ↓            ↓
  │                    │  BLOCKED  WAITING    TIMED_WAITING  (正常/異常結束)
  │                    │    ↑          ↑            ↑            ↓
  └────────────────────┴────┴──────────┴────────────┴──── TERMINATED

關鍵 API 分類詳解

1. 啟動與執行


public void start();      // 啟動線程,JVM 調用 run(),必須調用此方法而非直接調用 run()
public void run();        // 線程執行體,由 JVM 自動調用

2. 休眠與讓步 (靜態方法,作用於當前線程)


public static void sleep(long millis) throws InterruptedException;
public static void sleep(long millis, int nanos) throws InterruptedException;
public static void yield(); // 暫停當前線程,重新參與調度 (不保證成功)

注意:sleep() 不釋放鎖;yield() 僅是提示調度器。

3. 等待與通知 (Object 實例方法,需持有鎖)


public final void wait() throws InterruptedException;
public final void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException;
public final void notify();      // 喚醒單個等待線程
public final void notifyAll();   // 喚醒所有等待線程

模式:synchronized(lock) { while(condition) lock.wait(); }

4. 線程終止 (現代正確姿勢)

方法狀態評價
stop()Deprecated強制釋放鎖,導致數據不一致,嚴禁使用
interrupt()標準設置中斷標誌,推薦方式
volatile boolean running協作式業務標誌配合 interrupt() 雙重保障

正確中斷模式


public class Worker implements Runnable {
    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) { // 檢查中斷標誌
            try {
                doWork();
                Thread.sleep(1000); // 睡眠時若被中斷,拋出 InterruptedException
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // 重新設置標誌 (睡眠會清除)
                break; // 退出循環
            }
        }
        cleanup(); // 釋放資源
    }
}

// 主線程中斷
Thread t = new Thread(new Worker());
t.start();
// ... 
t.interrupt(); // 禮貌請求停止
t.join();      // 等待實際終止

5. 狀態查詢


public boolean isAlive();          // RUNNABLE/BLOCKED/WAITING/TIMED_WAITING 返回 true
public boolean isInterrupted();    // 實例方法:查詢該線程中斷標誌
public static boolean interrupted(); // 靜態方法:查詢並清除當前線程中斷標誌
public Thread.State getState();    // 獲取精確枚舉狀態 (監控/診斷用)

6. 線程合併


public void join() throws InterruptedException;
public void join(long millis) throws InterruptedException;
public void join(long millis, int nanos) throws InterruptedException;
// 作用:調用者等待目標線程終止。JMM 保證 join 返回前,目標線程所有寫入對調用者可見。

7. 棄用 API (僅供理解舊代碼)


@Deprecated public void suspend();   // 掛起,易死鎖
@Deprecated public void resume();    // 恢復
@Deprecated public void stop();      // 強制終止

實戰診斷技巧

  1. jstack pid 導出線程快照,分析狀態分佈
  2. ThreadMXBean 程序化監控:findDeadlockedThreads()、getThreadInfo()
  3. 日誌記錄關鍵狀態變更:Thread.currentThread().getState()

總結

Java 線程生命週期由 六大狀態 組成,核心操作集中在 啟動、休眠、等待/通知、中斷、合併。現代並發編程核心原則:拒絕 stop/suspend/resume,擁抱 interrupt + 協作式標誌 + 並發工具類 (Lock/Condition/CountDownLatch/CompletableFuture)。熟練掌握狀態轉換與 JMM 可見性保證,是寫出正確、高性能並發代碼的基石。

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