AQS讲解

1. AQS概述

AQS是一个抽象类,采用模板方法模式,定义了同步器的核心结构。子类通过继承AQS并实现其抽象方法(如tryAcquiretryRelease)来管理同步状态,而AQS负责线程的排队、阻塞与唤醒。


2. 核心组成

2.1 同步状态(State)
  • 通过volatile int state变量表示资源状态。
  • 子类通过CAS操作修改state,实现资源的获取与释放。
  • 例如:
    • ReentrantLockstate表示持有锁的线程的重入次数。
    • Semaphorestate表示可用许可数。
2.2 等待队列(CLH变种)
  • 使用双向链表实现FIFO队列,管理等待线程。
  • 每个节点(Node)封装一个线程及其状态(如CANCELLEDSIGNAL)。
  • 独占模式共享模式节点共存于同一队列,通过Node.nextWaiter区分。

3. 关键方法

3.1 模板方法
  • 获取资源
    • acquire(int arg):独占式获取,忽略中断。
    • acquireShared(int arg):共享式获取。
  • 释放资源
    • release(int arg):独占式释放。
    • releaseShared(int arg):共享式释放。
3.2 需子类实现的方法
  • tryAcquire(int arg):尝试独占获取。
  • tryRelease(int arg):尝试独占释放。
  • tryAcquireShared(int arg):尝试共享获取(返回剩余资源数)。
  • tryReleaseShared(int arg):尝试共享释放(返回是否成功)。

4. 工作流程

4.1 获取资源(以独占模式为例)
  1. 调用tryAcquire尝试直接获取资源。
  2. 若失败,将线程封装为节点加入队列尾部(addWaiter)。
  3. 自旋检查前驱节点是否为头节点,并尝试获取资源(acquireQueued)。
  4. 若成功,将当前节点设为头节点;否则,挂起线程(LockSupport.park)。
4.2 释放资源
  1. 调用tryRelease修改state
  2. 唤醒队列中下一个有效节点(unparkSuccessor)。

5. 公平性与非公平性

  • 非公平锁:线程可直接插队尝试获取资源(tryAcquire中不检查队列)。
  • 公平锁:仅在队列为空或当前线程是头节点时才尝试获取(hasQueuedPredecessors()检查)。

6. 条件变量(ConditionObject)

  • 每个条件变量对应一个等待队列。
  • await():释放锁,线程加入条件队列并阻塞。
  • signal():将节点从条件队列转移到主同步队列,等待获取锁。

7. 关键设计点

  • CAS操作:用于安全修改state和队列结构(如compareAndSetStatecompareAndSetTail)。
  • 自旋与挂起:减少上下文切换,仅在必要时挂起线程(如acquireQueued中的自旋检查)。
  • 传播机制:共享模式下,释放资源时唤醒后续多个节点(doReleaseShared)。

8. 典型应用

  • ReentrantLock:通过state实现可重入,区分公平/非公平。
  • Semaphore:共享模式控制并发数。
  • CountDownLatch:一次性屏障,state初始为计数。
  • ReentrantReadWriteLock:读写锁,高16位表示读锁,低16位表示写锁。

9. 示例代码(自定义互斥锁)

class Mutex extends AbstractQueuedSynchronizer {
    @Override
    protected boolean tryAcquire(int arg) {
        if (compareAndSetState(0, 1)) {
            setExclusiveOwnerThread(Thread.currentThread());
            return true;
        }
        return false;
    }

    @Override
    protected boolean tryRelease(int arg) {
        if (getState() == 0) throw new IllegalMonitorStateException();
        setExclusiveOwnerThread(null);
        setState(0);
        return true;
    }

    public void lock() { acquire(1); }
    public void unlock() { release(1); }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值