AbstractQueuedSynchronizer(以下簡稱 AQS)是 Java 並發包(java.util.concurrent)中鎖、信號量、屏障等同步組件的基石。理解 AQS,等於掌握了 JUC 同步機制的「心法」。本文系統梳理 AQS 的狀態管理、獨占/共享鎖流程、隊列機制與 Condition 實現。
getExclusiveOwnerThread()/setExclusiveOwnerThread(),記錄獨占鎖持有線程。int 狀態。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():當前線程是否持有獨占鎖。tryAcquire,失敗則 addWaiter 入隊,acquireQueued 自旋阻塞。tryRelease,成功則 unparkSuccessor 喚醒後繼節點。
適用於 ReadWriteLock 讀鎖、CountDownLatch、Semaphore 等場景。
tryAcquireShared(int arg):返回 ≥0 表示獲取成功(可傳遞剩餘資源數),<0 表示失敗。tryReleaseShared(int arg):返回 true 表示釋放成功需喚醒後繼。doAcquireShared 入隊自旋。
AQS 維护一個 FIFO 雙向隊列,節點類型 Node 包含 prev、next、thread、waitStatus、mode(獨占/共享)。
getQueueLength()、hasQueuedThreads()、getQueuedThreads()getFirstQueuedThread():獲取隊頭線程。hasQueuedPredecessors():公平鎖關鍵,判斷當前線程是否有前驅節點。hasContended():是否曾有線程入隊競爭過。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 源碼的關鍵鑰匙。