AQS : AbstractQueuedSynchronizer

19 阅读1分钟

它做了什么

提供一个基于 FIFO 的等待队列 + 一个原子状态值 state,配合 CAS + LockSupport.park/unpark,把“获取/释放资源”的通用流程封装好;具体如何占用/释放资源交给子类实现。

核心要点

  • 状态值 state(int) :表示资源占用数量或状态;独占/共享都用它表达。

  • 队列(CLH 变体) :获取失败的线程入队,按 FIFO 挂起/唤醒,支持公平/非公平两种策略。

  • 两种模式

    • 独占(exclusive) :如 ReentrantLock 的写锁。
    • 共享(shared) :如 Semaphore、CountDownLatch、ReentrantReadWriteLock 的读锁。
  • 模板方法(子类只需实现这些“钩子”)

    • tryAcquire(int) / tryRelease(int)
    • tryAcquireShared(int) / tryReleaseShared(int)
    • isHeldExclusively()
  • 已封装的获取/释放流程

    • acquire / release(独占)
    • acquireShared / releaseShared(共享)
    • 变体:acquireInterruptibly(可中断)、tryAcquireNanos(可超时
  • 条件队列 ConditionObject:支持多个条件变量(newCondition() 可创建多个),await/signal 的内部实现就是在条件队列同步队列间转移节点。

与 ReentrantLock 的对应关系

  • 可重入:ReentrantLock 在子类里额外记录当前持有线程,同线程二次获取时只做 state++。释放时 state-- 到 0 才真正唤醒后继。

  • 公平/非公平:通过是否在 tryAcquire 前检查队头是否自己来决定排队策略。

  • 可中断/可超时:直接复用 AQS 的 acquireInterruptibly、tryAcquireNanos。

  • 多条件队列:每个 Condition 就是 AQS 的 ConditionObject 实例。

迷你骨架(示意)

class MyLock {
  static class Sync extends AbstractQueuedSynchronizer {
    @Override protected boolean tryAcquire(int acquires) { /* 自定义占用逻辑 */ }
    @Override protected boolean tryRelease(int releases) { /* 自定义释放逻辑 */ }
    Condition newCondition() { return new ConditionObject(); }
  }
  private final Sync sync = new Sync();
  public void lock()   { sync.acquire(1); }
  public void unlock() { sync.release(1); }
  public Condition newCondition() { return sync.newCondition(); }
}

小结:AQS = “队列 + 状态 + CAS + 挂起/唤醒” 的通用同步器内核;ReentrantLock 等只是基于它填了具体的占用/释放细节与策略。