🧱 一、AQS 核心结构模拟类(简化版)
我们先定义一个最简化的 AbstractQueuedSynchronizer
类,用于后续同步器的模拟。
✅ SimpleAQS.java
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
public abstract class SimpleAQS {
private volatile int state;
private Node head;
private Node tail;
public int getState() {
return state;
}
protected void setState(int state) {
this.state = state;
}
protected boolean compareAndSetState(int expect, int update) {
return STATE_UPDATER.compareAndSet(this, expect, update);
}
private static final AtomicInteger STATE_OFFSET = new AtomicInteger(0);
private static final java.util.concurrent.atomic.AtomicReferenceFieldUpdater<SimpleAQS, Integer> STATE_UPDATER =
java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater(SimpleAQS.class, Integer.class, "state");
static final class Node {
Thread thread;
Node prev;
Node next;
Node nextWaiter; // for Condition
Node(Thread thread) {
this.thread = thread;
}
}
protected final void enqueue(Node node) {
for (;;) {
Node t = tail;
if (t == null) {
Node h = new Node(null); // Dummy header
if (STATE_UPDATER.compareAndSet(this, null, h)) {
head = h;
tail = h;
}
} else {
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return;
}
}
}
}
protected final boolean compareAndSetTail(Node expect, Node update) {
return java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater(SimpleAQS.class, Node.class, "tail")
.compareAndSet(this, expect, update);
}
protected final void park() {
LockSupport.park();
}
protected final void unparkSuccessor(Node node) {
Node next = node.next;
if (next != null)
LockSupport.unpark(next.thread);
}
}
🎯 二、四种同步器的 AQS 流程图
1️⃣ CountDownLatch(倒计时门闩)
📌 示例:初始值为 2,3 个线程等待
初始状态:
state = 2
head = null
tail = null
Thread T1 调用 await():
→ state > 0 → 入队 CLH
head → [T1] ← tail
Thread T2 调用 countDown():
→ state = 1
Thread T3 调用 countDown():
→ state = 0 → 唤醒所有等待线程
→ head = null, tail = null
T1 被唤醒:
→ 继续执行逻辑
2️⃣ CyclicBarrier(循环屏障)
📌 示例:初始值为 2,两个线程 await()
初始状态:
state = 2
Condition 队列: empty
CLH 队列: empty
Thread T1 调用 await():
→ 获取锁
→ --count = 1
→ index != 0 → trip.await()
→ 加入 Condition 队列
Thread T2 调用 await():
→ 获取锁
→ --count = 0
→ index == 0 → signalAll()
→ Condition 队列节点移入 CLH 队列
→ 唤醒 T1 → T1 unpark
→ 释放锁 → head = null, tail = null
3️⃣ ReentrantLock(可重入锁)
📌 示例:两个线程获取锁
初始状态:
state = 0
head = null
tail = null
Thread T1 调用 lock():
→ CAS 成功 → state = 1
Thread T2 调用 lock():
→ state == 1 → 入队 CLH
→ park(T2)
Thread T1 unlock():
→ state = 0
→ 唤醒 T2
Thread T2 被唤醒:
→ 获取锁 → 执行逻辑
4️⃣ Semaphore(信号量)
📌 示例:许可数为 3,5 个线程竞争
初始状态:
state = 3
head = null
tail = null
Thread T1 acquire(): state=2
Thread T2 acquire(): state=1
Thread T3 acquire(): state=0
Thread T4 acquire(): state=0 → 入队 CLH → park(T4)
Thread T5 acquire(): state=0 → 入队 CLH → park(T5)
Thread T1 release(): state=1 → 唤醒 T4
Thread T4 acquire(): state=0 → 执行完毕 → release → state=1 → 唤醒 T5
Thread T5 acquire(): state=0 → 执行完毕 → release → state=1
📦 三、完整模拟类实现(简化版)
✅ SimpleCountDownLatch.java
public class SimpleCountDownLatch extends SimpleAQS {
public SimpleCountDownLatch(int count) {
setState(count);
}
public void await() throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException();
if (getState() > 0) {
Node node = new Node(Thread.currentThread());
enqueue(node);
LockSupport.park();
}
}
public void countDown() {
if (getState() > 0 && compareAndSetState(getState(), getState() - 1)) {
if (getState() == 0) {
unparkSuccessor(head);
}
}
}
}
✅ SimpleSemaphore.java
public class SimpleSemaphore extends SimpleAQS {
public SimpleSemaphore(int permits) {
setState(permits);
}
public void acquire() throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException();
for (;;) {
int s = getState();
if (s > 0) {
if (compareAndSetState(s, s - 1)) break;
} else {
Node node = new Node(Thread.currentThread());
enqueue(node);
LockSupport.park();
}
}
}
public void release() {
setState(getState() + 1);
unparkSuccessor(head);
}
}
✅ SimpleReentrantLock.java
public class SimpleReentrantLock extends SimpleAQS {
private Thread owner;
public void lock() {
if (owner == null) {
owner = Thread.currentThread();
setState(1);
} else if (owner == Thread.currentThread()) {
setState(getState() + 1);
} else {
Node node = new Node(Thread.currentThread());
enqueue(node);
LockSupport.park();
}
}
public void unlock() {
if (owner == Thread.currentThread()) {
if (getState() == 1) {
owner = null;
setState(0);
unparkSuccessor(head);
} else {
setState(getState() - 1);
}
}
}
}
✅ SimpleCyclicBarrier.java
public class SimpleCyclicBarrier {
private final SimpleReentrantLock lock = new SimpleReentrantLock();
private final SimpleCondition condition = new SimpleCondition(lock);
private int parties;
private int count;
public SimpleCyclicBarrier(int parties) {
this.parties = parties;
this.count = parties;
}
public void await() throws InterruptedException {
lock.lock();
try {
count--;
if (count > 0) {
condition.await();
} else {
condition.signalAll();
}
} finally {
lock.unlock();
}
}
}
📚 四、使用示例(以 SimpleSemaphore
为例)
public class TestSimpleSemaphore {
public static void main(String[] args) {
SimpleSemaphore semaphore = new SimpleSemaphore(3);
for (int i = 0; i < 5; i++) {
new Thread(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " acquired");
Thread.sleep(1000);
semaphore.release();
System.out.println(Thread.currentThread().getName() + " released");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}