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

Java 線程實現原理與生命周期全面解析

     編輯:Java 相關知識

Java 線程的兩種實現方式

1. 繼承 Thread 類

public class MyThread extends Thread {
    @Override
    public void run() {
        // 線程執行邏輯
    }
}
// 使用
new MyThread().start();

2. 實現 Runnable 接口(推薦)

public class MyTask implements Runnable {
    @Override
    public void run() {
        // 任務邏輯
    }
}
// 使用
new Thread(new MyTask()).start();
// 或線程池
executor.submit(new MyTask());

優勢:避免單繼承限制,任務與線程控制解耦,方便線程池復用。

線程生命周期六大狀態

線程狀態轉換圖

狀態說明觸發條件
NEW新建Thread 對象創建,未調用 start()
RUNNABLE可運行調用 start(),等待 CPU 調度
BLOCKED阻塞等待獲取 synchronized 鎖
WAITING無限等待Object.wait()、Thread.join()、LockSupport.park()
TIMED_WAITING限時等待Thread.sleep()、wait(timeout)、join(timeout)
TERMINATED終止run() 正常結束或拋出未捕獲異常

關鍵狀態轉換詳解

RUNNABLE ↔ BLOCKED

  • 進入 synchronized 同步塊/方法 → 獲取鎖成功 → RUNNABLE
  • 獲取鎖失敗 → BLOCKED,鎖釋放後自動競爭恢復 RUNNABLE

RUNNABLE ↔ WAITING

  • obj.wait() 釋放鎖進入 WAITING
  • obj.notify()/notifyAll() 喚醒重新競爭鎖 → BLOCKED → RUNNABLE
  • thread.join() 等待目標線程終止

RUNNABLE ↔ TIMED_WAITING

  • Thread.sleep(ms)、obj.wait(ms)、thread.join(ms)
  • 超時自動喚醒或被 interrupt() 中斷 → 拋出 InterruptedException → RUNNABLE

線程常用操作方法

守護線程與用戶線程

  • 用戶線程:JVM 等待所有用戶線程結束才退出
  • 守護線程:為用戶線程服務(如 GC、Finalizer),所有用戶線程結束 JVM 自動退出
  • thread.setDaemon(true) 必須在 start() 前調用

線程組與優先級(了解即可)

  • 線程組:已被淘汰,不推薦使用
  • 優先級:MIN_PRIORITY=1 到 MAX_PRIORITY=10,NORM_PRIORITY=5,受 OS 調度影響大,不可靠

最佳實踐總結

  1. 優先使用 Runnable + 線程池 (ExecutorService)
  2. 正確處理中斷:while (!Thread.interrupted()) { ... }
  3. 避免使用 stop()、suspend()、resume() (已棄用,不安全)
  4. 共享資源加鎖用 synchronized 或 Lock,注意死鎖預防
  5. 線程池配置:CPU 密集型 N+1,IO 密集型 2N (N 為核心數)

掌握線程生命周期與狀態轉換,是編寫高併發、高穩定 Java 程序的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方法作用注意事項
start()啟動線程只能調用一次,二次調用拋 IllegalThreadStateException
run()執行邏輯直接調用不會新建線程,僅普通方法調用
sleep()靜態方法,讓當前線程休眠不釋放鎖,需捕獲 InterruptedException
yield()禮讓 CPU不保證調度,僅提示調度器
join()等待線程終止本質調用 wait(),可被中斷
interrupt()中斷線程設置中斷標誌,不會強制終止,需代碼配合檢查
isInterrupted()檢查中斷標誌不清除標誌
interrupted()靜態檢查並清除標誌僅當前線程可用