1. AQS核心原理与实现机制
AbstractQueuedSynchronizer(AQS)是Java并发包中的核心同步框架,它通过内置的FIFO队列管理线程的排队工作,并提供了可重写的方法来实现不同的同步策略。理解AQS的工作原理对于掌握Java并发编程至关重要。
1.1 CLH队列变体与状态管理
AQS采用CLH锁的变体实现,但与原始CLH锁的自旋机制不同,AQS通过park/unpark机制实现线程阻塞。其核心数据结构包含三个关键组件:
-
volatile int state:同步状态字段,不同子类对其语义定义不同:
- ReentrantLock:表示锁的重入次数
- Semaphore:表示可用许可数量
- CountDownLatch:表示剩余计数
-
Node双向队列:维护等待线程的CLH队列,包含:
- head指针:指向持有锁的线程节点
- tail指针:指向队列尾部用于快速插入新节点
- 前驱/后继指针:维护节点间关系
-
线程阻塞/唤醒机制:使用LockSupport的park/unpark实现高效线程调度
关键设计:当线程获取锁失败时,会创建Node节点加入队列尾部,并通过CAS保证线程安全。与原始CLH锁的自旋不同,AQS会让线程主动调用park()放弃CPU。
1.2 自定义AQS实现要点
要实现自定义同步器,需要重写以下模板方法:
java复制// 独占模式获取资源
protected boolean tryAcquire(int arg)
// 独占模式释放资源
protected boolean tryRelease(int arg)
// 共享模式获取资源
protected int tryAcquireShared(int arg)
// 共享模式释放资源
protected boolean tryReleaseShared(int arg)
// 是否独占模式
protected boolean isHeldExclusively()
实现示例:构建一个简单的二元闭锁
java复制class OneShotLatch {
private final Sync sync = new Sync();
private static class Sync extends AbstractQueuedSynchronizer {
protected int tryAcquireShared(int ignored) {
// 闭锁打开时返回1,否则返回-1
return (getState() == 1) ? 1 : -1;
}
protected boolean tryReleaseShared(int arg) {
setState(1); // 打开闭锁
return true;
}
}
public void signal() { sync.releaseShared(1); }
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
}
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 线程顺序执行方案对比
2.1 CAS自旋方案
通过volatile变量+原子操作实现简单顺序控制:
java复制public class CASSequence {
private static AtomicInteger state = new AtomicInteger(1);
class OrderedThread extends Thread {
private final int targetState;
private final int nextState;
OrderedThread(int target, int next, String name) {
super(name);
this.targetState = target;
this.nextState = next;
}
@Override
public void run() {
while(!state.compareAndSet(targetState, nextState)) {
Thread.yield(); // 避免忙等待
}
System.out.println(getName() + " executed");
}
}
public static void main(String[] args) {
CASSequence seq = new CASSequence();
new Thread(seq.new OrderedTh
