JUC-AQS源码详解

一:什么是AQS

AbstractQueuedSychronizer

整个JUC体系的基石,主要用于解决锁分配给“谁”的问题:

  • FIFO,CLH变体的虚拟双向对象
  • state:依靠单个原子int值来表示状态,通过占用和释放方法改变状态值

image.png
如果共享资源被占用,就需要一定的阻塞等待唤醒机制来保证锁分配。这个机制主要用的是CLH队列的变体实现的,将暂时获取不到锁的线程加入到队列中,这个队列就是AQS同步队列的抽象表现。它将要请求共享资源的线程及自身的等待状态(waitState)封装成队列的结点对象(Node) ,通过CAS、自旋以及LockSupport.park()的方式,维护state变 量的状态,使并发达到同步的效果。

二:AQS有关的锁

image.png
都是通过Sync实现AQS
image.png
相关关系图:NofairSync、FairSync(重点)
image.png

三:相关组成

3.1 AbstractQueuedSychronizer组成

AQS使用一个volatile的int类型的state来表示同步状态,通过内置的FIFO队列来完成资源获取的排队工作将每条要去抢占资源的线程封装成一个Node节点来实现锁的分配,通过CAS完成对State值的修改。
image.png

3.2 Node组成

image.pngimage.png

四:ReentrantLock原理为例

4.1 原理架构图

image.png

4.2 构造方法

可以实现非公平锁和公平锁
image.png
公平锁: 公平锁讲究先来先到,线程在获取锁时,如果这个锁的等待队列中已经有线程在等待,那么当前线程就会进入等待队列中;
非公平锁:不管是否有等待队列,如果可以获取锁,则立刻占有锁对象。也就是说队列的第一个排队线程苏醒后,不一定就是排头的这个线程获得锁,它还是需要参加竞争锁(存在线程竞争的情况下),后来的线程(队外的锁)可能不讲武德插队夺锁了。

4.3 lock方法

**非公平锁:lock方法 **
①第一个线程进来,此时无线程争抢,获取锁成功将state由0改为1
②第二个线程进来,此时cas发现状态位不为0,进入acquire尝试抢占
image.png
公平锁:lock方法
image.png

4.4 acquire方法

image.png
image.png
抢锁失败进入队列,

4.5 tryAcquire方法

模板方法交给子类实现
image.png
image.png
image.png
hasQueuedPredecessors.是公平锁加锁时判断等待队列中是否存在有效节点的方法

非公平锁:tryAcquire具体实现

image.png

4.6 addWaiter详解

image.png

image.png
image.png
入队操作三步:pre指向之前的尾节点,将此节点设置为尾节点,之前的尾节点的next指向当前节点。
image.png

4.7 acquireQueued方法

image.png
image.png
image.png

4.8 unlock方法

image.png
image.png
image.png
image.png
image.png

4.9 取消流程

image.png
image.png
image.png

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

噜啦啦412

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值