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

Java 多執行緒核心概念全解析:從原理到模型

     編輯:Java 相關知識

Java 內建多執行緒支援是其區別於傳統語言(如 C/C++ 需依賴 OS API)的重要特性。本文深入淺出解析執行緒基礎概念、進程與執行緒差異、Java 執行緒模型、優先級調度、同步機制與線程通訊,建立完整的併發知識骨架。

一、進程 vs 執行緒:顆粒度與資源的權衡

維度進程執行緒
定義執行中的程式,資源分配基本單位CPU 調度基本單位,輕量級進程
記憶體獨立位址空間,隔離性強共享進程堆/方法區,擁有私有棧/程式計數器
通訊成本高(IPC:管道、Socket、共享記憶體)低(直接讀寫共享變數)
切換開銷大(切換頁表、刷新 TLB)小(僅切換棧框架、寄存器)
穩定性崩潰不影響其他進程一條執行緒崩潰可能導致整個進程退出

結論:多進程適合隔離性要求高的場景(瀏覽器分頁);多執行緒適合高併發、資料共享密集的場景(Web 伺服器、遊戲引擎)。

二、Java 執行緒模型:從輪詢到搶佔式調度

1. 傳統單執行緒輪詢

事件迴圈不斷檢查事件隊列,CPU 空轉浪費;任一任務阻塞(I/O、睡眠)導致整個程式停滯。

2. Java 多執行緒優勢

  • 阻塞隔離:某執行緒等待網路/鎖/輸入時,其他執行緒繼續執行,CPU 利用率最大化。
  • 異步非阻塞:配合 NIO/CompletableFuture 實現高併發 I/O。
  • 響應性:GUI 事件派發執行緒(EDT)專職處理介面,耗時任務丟給背景執行緒。

3. 執行緒生命週期六大狀態

NEW → RUNNABLE → BLOCKED / WAITING / TIMED_WAITING → TERMINATED
  • RUNNABLE:包含 OS 的 READY 與 RUNNING,等待 CPU 時間片。
  • BLOCKED:等待 synchronized 鎖。
  • WAITING:無限期等待 Object.wait(), Thread.join(), LockSupport.park()。
  • TIMED_WAITING:帶超時的等待(sleep, wait(timeout), join(timeout))。

三、執行緒優先級與上下文切換

  • 優先級範圍 1~10(MIN_PRIORITY~MAX_PRIORITY),預設 5(NORM_PRIORITY)。
  • 搶佔式:高優先級執行緒可搶佔低優先級。
  • 自願讓出:sleep(), yield(), I/O 阻塞、鎖等待觸發切換。
  • 平台差異:Windows 時間片輪轉;Linux/Solaris 依賴 CFS 完全公平調度,優先級影響較小。
  • 警示:不要依賴優先級控制業務邏輯正確性,僅作為調度提示。

四、同步機制:管程與鎖

1. 隱式鎖

// 實例方法鎖住 this
public synchronized void deposit(int amt) { balance += amt; }

// 靜態方法鎖住 Class 物件
public static synchronized void reset() { ... }

// 同步區塊:鎖住任意物件,縮小鎖範圍
public void transfer(Account target, int amt) {
    synchronized(this) { synchronized(target) { ... } } // 注意死鎖風險,需固定鎖順序
}

2. 顯式鎖

ReentrantLock 提供可中斷鎖、公平鎖、條件變數(Condition)、嘗試鎖定(tryLock())等進階功能,JDK 1.5+ 首選。

3. 管程

Java 物件天生攜帶一把監視器鎖,synchronized 進入管程,wait/notify 在管程內等待/通知,實現「等待-通知」模式。

五、執行緒通訊:共享記憶體與訊息傳遞

模式核心 API適用場景
共享變數 + 同步volatile, synchronized, Lock, Atomic*高頻讀寫、簡單狀態同步
等待-通知Object.wait/notify, Condition.await/signal生產者-消費者、資源池
阻塞隊列BlockingQueue (ArrayBlockingQueue, LinkedBlockingQueue)解耦生產消費、背壓控制
Future/CompletableFutureFutureTask, CompletableFuture非同步計算結果獲取、組合
訊息傳遞Actor 模型、Disruptor、Channel (Go 風格庫)高併發、避免共享狀態、跨進程

六、Thread 與 Runnable:兩種創建方式

// 方式一:實作 Runnable(推薦,支援 Lambda、線程池複用)
Thread t = new Thread(() -> { /* task */ }, "Worker-1");
t.start();

// 方式二:繼承 Thread(侵入性強,單繼承限制)
class MyThread extends Thread { @Override public void run() { ... } }
new MyThread().start();

核心差異:Runnable 分離任務與執行載體,配合 ExecutorService 實現線程池複用;Thread 綁定任務與執行緒,不利擴展。

結語

理解執行緒模型、同步原理、通訊模式是寫出高效、正確併發程式的前提。實戰中優先使用 java.util.concurrent 高階組件(線程池、並發集合、同步器),減少手動 synchronized/wait/notify 的錯誤風險。

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