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

深度解析 Java 並發核心:AbstractQueuedSynchronizer (AQS) 原理與源碼詳解

     編輯:Java 綜合教學

前言

AbstractQueuedSynchronizer(以下簡稱 AQS)是 Java 並發包(java.util.concurrent)中鎖、信號量、屏障等同步組件的基石。理解 AQS,等於掌握了 JUC 同步機制的「心法」。本文系統梳理 AQS 的狀態管理、獨占/共享鎖流程、隊列機制與 Condition 實現。

核心類體系

  • AbstractOwnableSynchronizer:提供 getExclusiveOwnerThread()/setExclusiveOwnerThread(),記錄獨占鎖持有線程。
  • AbstractQueuedSynchronizer:核心實現,基於 int 狀態。
  • AbstractQueuedLongSynchronizer:基於 long 狀態,用於需要更大狀態值的場景。

子類(如 ReentrantLock、ReentrantReadWriteLock、CountDownLatch)通過實現 tryAcquire/tryRelease 等模板方法,定義具體的同步語義。

一、狀態管理

state 由子類賦予業務含義:如 ReentrantLock 表示重入次數,CountDownLatch 表示計數值,Semaphore 表示許可證數量。

  • getState():獲取當前狀態。
  • setState(int newState):設置狀態。
  • compareAndSetState(int expect, int update):CAS 修改狀態,保證原子性。

二、獨占鎖

適用於 ReentrantLock 等互斥鎖場景。

關鍵模板方法(子類實現)

  • tryAcquire(int arg):嘗試獲取鎖,成功返回 true,否則 false(進入隊列排隊)。
  • tryRelease(int arg):嘗試釋放鎖,成功返回 true(喚醒下一個節點),否則 false。
  • isHeldExclusively():當前線程是否持有獨占鎖。

核心流程

  1. acquire(arg):調用 tryAcquire,失敗則 addWaiter 入隊,acquireQueued 自旋阻塞。
  2. release(arg):調用 tryRelease,成功則 unparkSuccessor 喚醒後繼節點。

獨占鎖獲取釋放流程圖

三、共享鎖

適用於 ReadWriteLock 讀鎖、CountDownLatch、Semaphore 等場景。

關鍵模板方法(子類實現)

  • tryAcquireShared(int arg):返回 ≥0 表示獲取成功(可傳遞剩餘資源數),<0 表示失敗。
  • tryReleaseShared(int arg):返回 true 表示釋放成功需喚醒後繼。

核心流程

  1. acquireShared(arg):嘗試獲取,失敗進 doAcquireShared 入隊自旋。
  2. releaseShared(arg):釋放狀態,喚醒後繼節點(可能喚醒多個共享節點)。

共享鎖獲取釋放流程圖

四、同步隊列 (CLH 變體)

AQS 維护一個 FIFO 雙向隊列,節點類型 Node 包含 prev、next、thread、waitStatus、mode(獨占/共享)。

常用檢查方法

  • getQueueLength()、hasQueuedThreads()、getQueuedThreads()
  • getFirstQueuedThread():獲取隊頭線程。
  • hasQueuedPredecessors():公平鎖關鍵,判斷當前線程是否有前驅節點。
  • hasContended():是否曾有線程入隊競爭過。

五、Condition 實現

ConditionObject 是 AQS 內部類,實現 Condition 接口,每個 Condition 對應一個單向等待隊列(firstWaiter/lastWaiter)。

核心操作

  • await():當前線程釋放鎖,構造節點加入 Condition 隊列,阻塞等待。
  • signal():將 Condition 隊列頭節點移至同步隊列尾部,等待重新競爭鎖。

監控方法

  • owns(ConditionObject)、hasWaiters(ConditionObject)、getWaitQueueLength(ConditionObject)、getWaitingThreads(ConditionObject)

總結

AQS 採用「模板方法模式」+「CLH 隊列變體」+「CAS 狀態更新」的設計,將同步狀態管理、線程排隊阻塞/喚醒、條件等待等通用邏輯下沉,極大降低了自定義同步組件的開發難度。掌握 tryAcquire/Release 與 tryAcquireShared/ReleaseShared 的語義契約,是閱讀 JUC 源碼的關鍵鑰匙。

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