Java 并發核心:AQS(AbstractQueuedSynchronizer) 詳解

一、什么是 AQS?

AbstractQueuedSynchronizer(簡稱 AQS)是 Java 并發包 java.util.concurrent.locks 中的一個核心同步框架,用于構建鎖和同步器,如:

  • ReentrantLock
  • ReentrantReadWriteLock
  • CountDownLatch
  • Semaphore
  • FutureTask

AQS 通過一個FIFO 雙向等待隊列(CLH 隊列)管理線程的同步狀態,使開發者可以專注于同步邏輯,而不必關注線程的調度、阻塞、喚醒等底層細節。


二、AQS 的核心設計

1. 核心成員變量

private volatile int state;       // 同步狀態
private transient Node head;      // 隊列頭節點
private transient Node tail;      // 隊列尾節點
  • state:用來表示資源的占用狀態(例如是否被鎖定、可用信號量數等);
  • headtail:維護一個 CLH 等待隊列,用于管理阻塞的線程。

2. 核心方法(模板方法)

AQS 提供一系列模板方法用于子類實現:

// 共享模式
protected int tryAcquireShared(int arg);
protected boolean tryReleaseShared(int arg);// 獨占模式
protected boolean tryAcquire(int arg);
protected boolean tryRelease(int arg);

子類需要實現這些方法,以控制對資源的獲取與釋放邏輯。


三、AQS 工作流程

1. 獲取鎖(以獨占模式為例)

lock.lock() → tryAcquire() 嘗試獲取 → 獲取失敗 → 加入 CLH 隊列 → park(阻塞)→ 被喚醒時再次嘗試

流程:

  1. 調用 tryAcquire() 嘗試獲取資源;
  2. 如果失敗,則將當前線程封裝為 Node 加入等待隊列;
  3. 阻塞(park)當前線程;
  4. 資源釋放后,喚醒下一個等待線程。

2. 釋放鎖

unlock() → tryRelease() 成功 → 喚醒隊列中下一個線程
  • tryRelease()state 設置為 0;
  • 然后調用 unparkSuccessor() 喚醒下一個線程。

四、獨占模式 vs 共享模式

模式描述
獨占模式同一時刻只能有一個線程訪問,如 ReentrantLock
共享模式多個線程可以共享資源,如 Semaphore、CountDownLatch

AQS 區分這兩種模式,并分別處理入隊、出隊、喚醒等邏輯。


五、CLH 隊列機制

AQS 使用一種變體的 CLH(Craig–Landin–Hagersten)同步隊列 實現線程排隊。

隊列結構:

head -> Node1 -> Node2 -> ... -> tail
  • 每個節點是一個線程的等待快照;
  • 新線程失敗后加入尾部,前驅釋放時喚醒后繼;
  • 自旋或 park 阻塞等待。

六、典型用法示例

自定義鎖的基本寫法

class MyLock extends AbstractQueuedSynchronizer {protected boolean tryAcquire(int arg) {return compareAndSetState(0, 1);}protected boolean tryRelease(int arg) {setState(0);return true;}public void lock() {acquire(1); // 內部調用 tryAcquire + 入隊邏輯}public void unlock() {release(1);}
}

CountDownLatch 原理

  • 使用共享模式;
  • 每次 countDown() 執行 releaseShared(-1)
  • await() 會在 state = 0 前阻塞。

七、AQS 的優點

優點說明
封裝阻塞邏輯使用 LockSupport 封裝了 park/unpark
可復用性強模板方法模式,便于自定義同步器
隊列高效FIFO 隊列實現公平性,性能穩定
支持兩種模式支持共享和獨占資源控制

八、注意點 & 問題排查

  1. 死鎖:一定要在 try...finally 中釋放鎖;
  2. state 狀態:設計時需合理設置 state 的含義(計數、二進制等);
  3. CLH 隊列泄露:釋放時未正確調用 unpark 會導致阻塞線程永久等待;
  4. 性能瓶頸:高并發下需注意鎖競爭,考慮使用 StampedLock 或樂觀鎖優化。

九、AQS 應用類匯總

類名模式簡介
ReentrantLock獨占可重入、可中斷、公平/非公平
Semaphore共享控制資源訪問數目
CountDownLatch共享等待所有任務完成
ReentrantReadWriteLock共享 + 獨占高效讀寫分離
FutureTask獨占控制異步任務狀態
AbstractQueuedSynchronizer基類框架級同步器

十、總結

  • AQS 是構建 Java 同步工具的核心;
  • 通過隊列管理線程阻塞與喚醒;
  • 使用模板方法封裝了多種模式;
  • 掌握 AQS = 掌握 Java 并發的核心原理。

補充:AQS 源碼流程圖解析 + ReentrantLock 實戰源碼


一、AQS 獲取鎖(acquire)源碼流程

public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();
}

流程圖解:

             acquire()│┌───────┴────────┐↓                ↓tryAcquire()     // 自定義嘗試獲取(成功返回true)     (失敗)↓                ↓return      addWaiter(Node.EXCLUSIVE)↓入隊列構造雙向鏈表↓acquireQueued(node, arg)↓while(前驅不是head || 不能獲取鎖)↓        ↓park()   tryAcquire()↓獲取成功 → 設置head → unpark下一個

二、AQS 釋放鎖(release)源碼流程

public final boolean release(int arg) {if (tryRelease(arg)) {Node h = head;if (h != null && h.waitStatus != 0)unparkSuccessor(h);return true;}return false;
}

流程圖解:

            release()│tryRelease()│是否成功釋放?↓   ↑true  false↓獲取 head↓喚醒下一個節點(unpark)

三、ReentrantLock 是怎么用 AQS 實現的?

源碼結構簡圖:

public class ReentrantLock implements Lock {abstract static class Sync extends AbstractQueuedSynchronizer {// 核心邏輯都在此子類中}final Sync sync;
}

ReentrantLock 的兩個實現版本:

類型類名特點
非公平鎖(默認)NonfairSync直接嘗試獲取鎖,搶占式,性能好
公平鎖FairSync排隊獲取,按順序,不插隊,公平但慢一些

tryAcquire 的實現(非公平鎖)

protected final boolean tryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {// 嘗試直接 CAS 獲取鎖if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}} else if (current == getExclusiveOwnerThread()) {// 可重入,加重入次數int nextc = c + acquires;setState(nextc);return true;}return false;
}

tryRelease 的實現

protected final boolean tryRelease(int releases) {int c = getState() - releases;if (Thread.currentThread() != getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free = false;if (c == 0) {free = true;setExclusiveOwnerThread(null);}setState(c);return free;
}

四、AQS 線程狀態控制核心機制:LockSupport

AQS 底層通過 LockSupport.park()unpark(thread) 來掛起/喚醒線程:

  • park():當前線程阻塞,等待被喚醒;
  • unpark(Thread t):喚醒指定線程;
  • 這種控制機制替代了傳統的 wait/notify,更靈活、底層、性能好。

五、總結:如何理解 AQS 的強大之處?

特性說明
模板方法設計只需實現 tryAcquiretryRelease,其他線程隊列處理由 AQS 自動完成
雙模式支持支持共享與獨占兩種訪問模型
高可復用性可構建多種同步組件(鎖、信號量、柵欄等)
高性能結合 CAS、自旋、隊列掛起喚醒機制
阻塞線程管理使用 LockSupport 精細控制線程掛起與恢復

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/87527.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/87527.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/87527.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LoRA 實戰指南:NLP 與 CV 場景的高效微調方法全解析

大模型已成 AI 應用的“標配”,但高昂的訓練和部署成本讓很多企業望而卻步。LoRA(Low-Rank Adaptation)作為一種輕量級微調方案,正成為 NLP 與 CV 場景中低成本定制的利器。本文詳細通過詳細介紹 LoRA 的核心原理、在文本與圖像任…

centos指令

一、python 1、查詢運行中腳本 ps aux | grep python2、關閉腳本進程 kill -15 <PID> # 優雅終止&#xff08;SIGTERM&#xff09; kill -9 <PID> # 強制終止&#xff08;SIGKILL&#xff09;

用c語言寫一個找兩張圖片不同處的游戲

回答 思考完成 我們計劃開發一個用C語言實現的查找兩張圖片不同之處的游戲。這個程序需要加載兩張圖片&#xff0c;然后允許用戶通過點擊等方式標記出差異的位置。我們將使用一個簡單的圖形庫&#xff08;例如SDL&#xff09;來處理圖像和用戶交互。步驟&#xff1a;1.加載兩…

【深度學習:進階篇】--4.3.seq2seq與Attention機制

學習目標 目標 掌握seq2seq模型特點掌握集束搜索方式掌握BLEU評估方法掌握Attention機制 應用 應用Keras實現seq2seq對日期格式的翻譯 目錄 學習目標 1.seq2seq 1.1.定義 1.2.條件語言模型理解 1.3.應用場景 2.注意力機制 2.1.長句子問題 2.2.定義 2.3.公式 3.機器…

MYSQL與PostgreSQL的差異

一、架構設計的根本差異 進程模型 vs 線程模型 ?PostgreSQL?&#xff1a;采用多進程架構&#xff08;每個連接獨立進程&#xff09;&#xff0c;通過共享內存通信。優勢在于進程隔離性強&#xff0c;單連接崩潰不影響整體服務&#xff0c;但資源消耗較高。 ?MySQL?&…

Wpf布局之StackPanel!

文章目錄 前言一、引言二、使用步驟 前言 Wpf布局之StackPanel&#xff01; 一、引言 StackPanel面板在水平或垂直的堆棧中放置元素。這個布局容器通常用于更大、更復雜窗口中的一些區域。 二、使用步驟 StackPanel默認是垂直堆疊 <Grid><StackPanel><Butt…

【MySQL】 內置函數

目錄 1.時間函數2.字符串函數3.數學函數4.其他函數 1.時間函數 函數名稱描述current_date()當前日期current_time()當前時間current_timestamp()當前時間戳date(datetime)返回datetime參數的日期部分date_add(date,interval d_value_type)在date中添加日期/時間&#xff0c;in…

【RK3568+PG2L50H開發板實驗例程】Linux部分/FAN 檢測案例

本原創文章由深圳市小眼睛科技有限公司創作&#xff0c;版權歸本公司所有&#xff0c;如需轉載&#xff0c;需授權并注明出處&#xff08;www.meyesemi.com) 1.案例簡介 本案例旨在介紹如何測試開發板上風扇接口控制風扇啟停與調速功能 2. FAN接口介紹 開發板上 FAN接口是一個…

Spring AI ETL Pipeline使用指南

前言&#xff08;Introduction&#xff09; 版本聲明&#xff1a;本文基于 Spring AI 1.0.0 版本編寫。由于 Spring AI 目前仍處于活躍開發階段&#xff0c;API 和組件可能在后續版本中發生變化&#xff0c;請注意及時關注官方文檔更新以保持兼容性。 在當今大數據和人工智能快…

Docker 入門教程(九):容器網絡與通信機制

文章目錄 &#x1f433; Docker 入門教程&#xff08;九&#xff09;&#xff1a;容器網絡與通信機制一、Docker 網絡模型二、Docker 的四種網絡類型三、容器間通信機制四、相關指令 &#x1f433; Docker 入門教程&#xff08;九&#xff09;&#xff1a;容器網絡與通信機制 一…

從進攻性安全角度簡析 Windows PowerShell

PowerShell 是 Windows 系統中強大的腳本語言和命令行工具&#xff0c;因其靈活性和與 .NET 框架的深度集成&#xff0c;成為攻擊者執行惡意操作的熱門選擇。從進攻性安全視角看&#xff0c;PowerShell 的語言模式、執行策略&#xff08;Execution Policy&#xff09;、AMSI 繞…

MySQL的深度分頁如何優化!

MySQL深度分頁&#xff08;例如 LIMIT 1000000, 20&#xff09;性能差的主要原因在于 OFFSET 需要掃描并跳過大量數據&#xff0c;即使這些數據最終并不返回。隨著 OFFSET 增大&#xff0c;性能會急劇下降。 以下是優化深度分頁的常用策略&#xff0c;根據場景選擇最適合的方案…

K8s Pod 調度基礎——1

目錄 一、Replication Controller&ReplicaSet ?一、Replication Controller (RC)? ?原理? ?特性? ?意義? ?示例與逐行解釋? ?二、ReplicaSet (RS)? ?原理? ?特性? ?意義? ?示例與逐行解釋? ?三、RC 與 RS 的對比? ?四、總結? 二、Dea…

C# Task異步的常用方法

Task異步的常用方法 C# 中的 Task 類是 System.Threading.Tasks 命名空間的一部分&#xff0c;用于表示異步操作。 一、Task.Run(Action action): 此靜態方法用于在后臺運行一個新任務&#xff0c;并返回與該任務關聯的 Task 實例。 本質是將任務放入線程池執行&#xff0c;自…

OpenResty實戰之PB級物聯網數據處理:時序數據庫優化實戰

某智慧能源平臺通過本方案成功處理了日均1.2萬億數據點&#xff0c;存儲成本降低70%&#xff0c;查詢延遲從分鐘級優化到亞秒級。本文將深入解析PB級物聯網數據處理的核心挑戰與時序數據庫深度優化技巧。 一、物聯網數據特性與存儲挑戰 1.1 物聯網數據核心特征 #mermaid-svg-U…

聊聊架構(5)數字化時代的平臺商業架構

在數字化浪潮的推動下&#xff0c;平臺經濟已成為全球經濟增長的關鍵驅動力。作為架構師&#xff0c;不僅要精通架構設計的基礎方法論&#xff0c;還需具備敏銳的商業洞察力。架構的價值在于服務業務和商業&#xff0c;而業務的發展又促使架構不斷演進。本文將深入探討平臺的商…

【數據增強】精細化貼圖數據增強

1.任務背景 假設我有100個蘋果的照片&#xff0c;我需要把這些照片粘貼到傳送帶照片上&#xff0c;模擬“傳送帶蘋果檢測”場景。 這種貼圖的方式更加合理一些&#xff0c;因為yolo之類的mosaic貼圖&#xff0c;會把圖像弄的非常支離破碎。 現在我需要隨機選擇幾張蘋果圖像&am…

HTML響應式Web設計

什么是響應式Web設計&#xff1f; RWD指的是響應式Web設計&#xff08;Responsive Web Design)RWD能夠以可變尺寸傳遞網頁RWD對于平板和移動設備是必需的 創建一個響應式設計&#xff1a; <!DOCTYPE html> <html lang"en-US"> <head> <styl…

【讀代碼】百度開源大模型:ERNIE項目解析

一、項目基本介紹 1.1 項目概述 ERNIE(Enhanced Representation through kNowledge IntEgration)是百度基于PaddlePaddle深度學習框架開發的多模態預訓練模型體系。最新發布的ERNIE 4.5系列包含10個不同變體,涵蓋從300B參數的巨型MoE模型到0.3B的輕量級模型,形成完整的多…

2025年6月:技術探索與生活平衡的協奏曲

> 當代碼與晨跑軌跡在初夏的陽光下交織,我找到了程序員生活的黃金分割點 --- ### 一、技術突破:AI驅動的智能工作流優化系統 這個月我成功部署了第三代自動化工作流系統,核心創新在于**動態決策樹+實時反饋機制**。系統可自主優化處理路徑,錯誤率下降62%! ```pyth…