AQS执行逻辑

1、假设有线程去获取公平锁FairLock,线程去执行lock()方法:

  if (!tryAcquire(arg) &&
      acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
      selfInterrupt();

2、tryAcquire(1) 代码的含义:如果state为0(锁没有被线程占用)或者独占线程是当前线程时,获取锁成功,并且更改独占线程为自己,state++。
addWaiter的含义:将当前Node放在双向队列的结尾。
acquireQueued的含义:当前Node的前驱节点是不是head,如果是,当前Node(线程)尝试去获取锁,获取成功后,把它自己设置成head,返回;如果获取锁失败,进入等待(UNSAFE.park),直到被唤醒,唤醒后重复前面的过程。
selfInterrupt:如果线程有中断过,那么最后增加中断标记(被唤醒后中断标记会别清空),在执行lockInterruptibly的时候,抛出InterruptedException异常,参考AQS的acquireInterruptibly方法。

3、当head节点的线程执行完后,操作release释放锁。

    public final boolean release(int arg) {
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }

4、tryRelease(1) 主要是将state–,如果state为0,独占线程设置为空。
unparkSuccessor(head) 的含义:将head的后驱节点唤醒(UNSAFE.unpark),后驱节点被唤醒后就会尝试去获取锁。

AQS的处理的最核心的方法是acquireQueued,它是通过自旋、CAS、park/unpark实现线程排队获取锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值