# 如何理解AQS源碼
## 目錄
1. [AQS概述](#1-aqs概述)
1.1 [什么是AQS](#11-什么是aqs)
1.2 [AQS的核心思想](#12-aqs的核心思想)
1.3 [AQS的應用場景](#13-aqs的應用場景)
2. [AQS核心數據結構](#2-aqs核心數據結構)
2.1 [同步狀態state](#21-同步狀態state)
2.2 [CLH隊列](#22-clh隊列)
2.3 [Node節點解析](#23-node節點解析)
3. [獨占模式源碼分析](#3-獨占模式源碼分析)
3.1 [acquire流程](#31-acquire流程)
3.2 [release流程](#32-release流程)
4. [共享模式源碼分析](#4-共享模式源碼分析)
4.1 [acquireShared流程](#41-acquireshared流程)
4.2 [releaseShared流程](#42-releaseshared流程)
5. [條件隊列實現原理](#5-條件隊列實現原理)
5.1 [ConditionObject結構](#51-conditionobject結構)
5.2 [await實現機制](#52-await實現機制)
5.3 [signal實現機制](#53-signal實現機制)
6. [AQS設計模式分析](#6-aqs設計模式分析)
6.1 [模板方法模式應用](#61-模板方法模式應用)
6.2 [CLH隊列變體](#62-clh隊列變體)
7. [常見同步器實現分析](#7-常見同步器實現分析)
7.1 [ReentrantLock](#71-reentrantlock)
7.2 [CountDownLatch](#72-countdownlatch)
7.3 [Semaphore](#73-semaphore)
8. [AQS性能優化策略](#8-aqs性能優化策略)
8.1 [自旋優化](#81-自旋優化)
8.2 [隊列頭尾競爭優化](#82-隊列頭尾競爭優化)
9. [AQS面試深度剖析](#9-aqs面試深度剖析)
10. [總結與最佳實踐](#10-總結與最佳實踐)
---
## 1. AQS概述
### 1.1 什么是AQS
AbstractQueuedSynchronizer(AQS)是Java并發包中的核心框架,自JDK1.5引入,位于`java.util.concurrent.locks`包下。作為構建鎖和同步器的基石,其設計采用模板方法模式,通過繼承方式實現自定義同步控制。
```java
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer {
// 同步狀態字段
private volatile int state;
// CLH隊列頭節點
private transient volatile Node head;
// CLH隊列尾節點
private transient volatile Node tail;
}
state
表示資源狀態tryAcquire
/tryRelease
等待實現方法// 使用CAS保證原子性更新
protected final boolean compareAndSetState(int expect, int update) {
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
狀態含義取決于實現: - ReentrantLock:表示重入次數 - Semaphore:表示可用許可數
CLH(Craig, Landin, Hagersten)隊列變體特點: 1. 雙向鏈表結構 2. 通過前驅節點的status進行自旋避免競爭 3. 頭部節點為虛節點(dummy node)
static final class Node {
// 節點模式
static final Node SHARED = new Node();
static final Node EXCLUSIVE = null;
// 等待狀態
volatile int waitStatus;
static final int CANCELLED = 1;
static final int SIGNAL = -1;
// 前后指針
volatile Node prev;
volatile Node next;
// 關聯線程
volatile Thread thread;
}
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
關鍵操作: - unparkSuccessor喚醒后繼節點 - 保證喚醒傳播性
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
與獨占模式區別: - 返回值表示剩余資源量 - 使用setHeadAndPropagate傳播喚醒
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
通過自旋保證: - 穩定狀態傳播 - 處理競爭情況
public class ConditionObject implements Condition {
private transient Node firstWaiter;
private transient Node lastWaiter;
}
與同步隊列關系: - 共享state狀態 - 節點類型不同(CONDITION=-2)
public final void signal() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node first = firstWaiter;
if (first != null)
doSignal(first);
}
關鍵步驟: - 轉移節點到同步隊列 - 修改waitStatus狀態
需要子類實現的方法:
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
改進點: 1. 顯式維護前驅指針 2. 增加超時/Cancellation處理 3. 虛擬頭節點減少競爭
公平鎖實現:
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
// 處理重入...
}
共享模式典型應用:
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
在shouldParkAfterFailedAcquire中:
if (ws > 0) {
// 跳過取消的節點
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
} else {
// 設置SIGNAL狀態
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
采用延遲初始化:
private Node enq(final Node node) {
for (;;) {
Node t = tail;
if (t == null) { // 必須初始化
if (compareAndSetHead(new Node()))
tail = head;
} else {
// 正常入隊邏輯...
}
}
}
高頻問題:
1. state為什么用int而不是long?
大多數場景int足夠,且JVM對int有更好的CAS支持
為什么CLH隊列需要虛擬頭節點?
減少邊界條件判斷,統一處理邏輯
如何處理取消的節點?
通過waitStatus=CANCELLED標記,在隊列遍歷時跳過
本文通過1.7萬字系統分析了AQS的實現原理,建議讀者結合JDK源碼進行調試分析,理解每個細節的設計考量。 “`
注:實際完整文章應包含更多代碼示例、流程圖(可用mermaid語法)、性能對比數據等。以上為精簡框架,完整內容需要展開每個小節的詳細分析,補充具體場景案例和更深入的實現細節討論。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。