AQS源码详解

什么是AQS

AQS是AbstractQueuedSynchronizer即抽象队列同步器。JUC中的很多类都用到了AbstractQueuedSynchronizer。如ReentrantLock、CountDownLatch、Semaphore底层都是实现了AbstractQueuedSynchronizer
在这里插入图片描述
在这里插入图片描述

代码解析

ReentrantLock加锁
当我们使用ReentrantLock时发生了什么事呢?
在这里插入图片描述
ReentrantLock默认创建一个非公平所,并赋给sync;
在这里插入图片描述
Sync类继承了AbstractQueuedSynchronizer;点进NonfairSync
在这里插入图片描述
可以看到调用lock时,if会去判断state是否等于0,如果等于0,则将state设为1;并将锁的持有者设为当前线程,若state等于1,则说明当前有人在使用锁,假设现在有线程持有锁,进入acquire
在这里插入图片描述
点击计入tryAcquire
在这里插入图片描述
找到NonfairSync对tryAcquire的重写方法
在这里插入图片描述
点击进入nonfairTryAcquire
在这里插入图片描述
假设现在state大于0,说明当前有线程持有这把锁,则运行else if (current == getExclusiveOwnerThread())。判断当前线程和持有这把锁的线程是否属于同一个线程,如果属于同一个线程,则返回true。这就是ReentrantLock属于可重入锁的原因。如果state等于0,则说明当前没有线程占用该锁,将state设为1,把锁的拥有者设为当前线程。
在这里插入图片描述
接着进入acquire的第二个判断中的addWaiter中
在这里插入图片描述
这个方法将会判断当前队列是否为空,若为空,则在队列的最前面创建一个空节点node,并将排队的节点封装成一个node加入到队列中;
在这里插入图片描述
进入到acquireQueued中
在这里插入图片描述
若当前线程的前一个节点是头节点,则尝试再次获取锁,若获取失败,则进入shouldParkAfterFailedAcquire中
在这里插入图片描述
由于默认当前节点的前一个节点的watistatus = 0,则执行compareAndSetWaitStatus(pred, ws, Node.SIGNAL);将当前一个节点的watistatus设为Node.SIGNAL == -1,返回false
在这里插入图片描述
循环继续执行,继续进入到shouldParkAfterFailedAcquire,由于刚刚把当前一个节点的watistatus设为-1了,则会满足ws == Node.SIGNAL返回true
在这里插入图片描述
返回true后会执行parkAndCheckInterrupt
在这里插入图片描述
该方法使用LockSupport.park(this)将线程阻塞
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值