AQS原理解析

AQS

AQS这个类定义了一套多线程访问共享资源的同步器框架,AQS是整个JUC包的基石,JUC包内几乎所有线程间同步的组件都依赖于AQS。AQS简单来说就是用来同步的,主要是维护了一个state变量和一个CLH同步队列。

AQS建议实现类定义为非public的内部类。因为AQS其实是一个抽象的同步器,一个同步框架,封装了通用的同步逻辑,大多数时候实现类可以看成一个适配器,比如ReentrantLock中的Sync修饰关键字为static final.
在这里插入图片描述

独占模式和共享模式

AQS有独占和共享两种实现方式。

在这里插入图片描述
在这里插入图片描述
独占锁和共享锁获取同步状态都是调用这个方法,aquire方法用一个布尔型变量来区分独占/共享,独占锁和共享锁的区别主要是state变量,独占锁state变量肯定是0或1,共享锁state>0;独占锁释放锁后唤醒下一个结点,共享锁唤醒所有结点。

CLH队列

CLH队列是AQS的核心组件。AQS将每个等待锁的线程封装成Node结点,并维护由这些Node组成的CLH队列(可以看成一个双向链表,每个Node都有前驱和后继指针)和一个int类型的核心变量state,用来记录当前的状态。当发生竞争的时候,AQS会将线程封装为Node并入队等待。
在这里插入图片描述
在这里插入图片描述
Node入队
在这里插入图片描述

  1. 将待入队结点的前驱设置为当前队列的tail
  2. 如果tail此时为null,说明队列为空,尝试CAS设置一个哨兵结点作为队列的head,如果CAS成功则将tail也指向该哨兵结点(dummy node,链表题经常用到的)
    在这里插入图片描述
  3. 否则直接CAS设置tail指向待入队的结点
  4. 自旋重试直到步骤3成功。

acquire,获取同步状态。
在这里插入图片描述
获取锁流程:

  1. acquire(1)
  2. 首先调用tryAcquire(1)
  3. 如果不成功则将 进入acquire(Node node, int arg, boolean shared,
    boolean interruptible, boolean timed, long time) 这个方法,这个方法代码很长,先考虑了当前队列为空、或者当前结点是第一个结点等等一些列情况最终才创建结点并入队。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值