Java并发编程之AQS

  • tryAcquire(int arg)
  • acquire(int arg)
  • tryRelease(int arg)
  • release(int arg)

1. AQS 内部状态 state

  • state 变量
    AQS 内部通过一个 volatile int state 来记录当前同步状态。

    • 对于简单的非重入锁,通常 state 为 0 表示锁处于空闲状态,为 1 表示锁被占用。
    • 对于重入锁,state 可以累加,用来记录同一线程重入的次数。
  • CAS 操作
    AQS 使用CAS操作来原子性地修改 state,从而保证并发场景下状态更新的安全性。


2. tryAcquire(int arg)

  • 作用

    • 在这个方法中,会根据当前 state 的值判断能否获得锁。
    • 如果 state 为 0(锁空闲),则尝试通过 CAS 操作将 state 更新为非 0(例如 1 或者 arg 表示的值),同时记录当前线程为锁的持有者。
    • 如果是重入场景,并且当前线程已经持有锁,则可以让 state 累加,允许重入。
  • 示例代码(非重入锁)

    protected boolean tryAcquire(int acquires) {
        // 如果 state 为 0,尝试获取锁
        if (compareAndSetState(0, acquires)) {
            // 设置当前线程为独占线程
            setExclusiveOwnerThread(Thread.currentThread());
            return true;
        }
        return false;
    }
    

    在这个过程中,compareAndSetState(0, acquires) 就是对 state 的显式设置,它保证只有一个线程能成功更新 state,从而获得锁。


3. acquire(int arg)

  • 作用

    • 当线程调用 acquire(arg) 时,AQS 会先调用 tryAcquire(arg)
    • 如果 tryAcquire(arg) 返回 true,说明锁已成功获取;
    • 否则,线程会被加入到 AQS 内部的 FIFO 队列中,进入等待状态,直到获取锁。
  • 工作流程

    1. 调用 tryAcquire(arg) 尝试获取锁。
    2. 如果失败,调用 addWaiter(Node.EXCLUSIVE) 将线程包装成节点添加到等待队列。
    3. 进入自旋或阻塞状态,等待前驱节点释放锁并唤醒自己,最终再次尝试获取锁。

4. tryRelease(int arg)

  • 作用

    • 它会根据当前 state 的值来判断是否能释放锁。
    • 对于重入锁,通常是将 state 减少 arg,当 state 减少到 0 时,表示完全释放锁,并清除当前线程的持有标记。
  • 示例代码(非重入锁)

    protected boolean tryRelease(int releases) {
        // 对于非重入锁,直接判断 state 是否为 0
        if (getState() == 0) {
            throw new IllegalMonitorStateException();
        }
        // 释放锁,将 state 设为 0,并清除当前持有线程
        setExclusiveOwnerThread(null);
        setState(0);
        return true;
    }
    

5. release(int arg)

  • 作用

    • 它内部会调用开发者实现的 tryRelease(arg)
    • 如果 tryRelease(arg) 返回 true,表示锁完全释放,那么 AQS 会唤醒等待队列中的下一个线程。
  • 工作流程

    1. 调用 tryRelease(arg) 尝试释放锁。
    2. 如果返回 true,说明锁释放成功,接下来调用 unparkSuccessor(Node node) 来唤醒等待队列中的后继节点,从而使其他等待线程有机会重新竞争锁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值