AQS的初步了解

原文链接:AQS的初步了解 – 编程屋

目录

1 什么是AQS

2 ReentrantLock加锁和释放锁的底层原理

1 什么是AQS

AQS(AbstractQueuedSynchronizer): 是jdk提供的一个同步框架,内部维护着FIFO双向队列,即CLH同步队列。

AQS依赖它来完成同步状态的管理(volatile修饰的state,用于标志是否持有锁)。如果获取同步状态state失败时,会将当前线程和等待信息构建成一个Node节点。将Node放到FIFO队列中,同时阻塞当前线程,当前线程同步状态state释放时,会把FIFO队列中的首节点唤醒,使其获取同步状态state。

  /**
   * The synchronization state.
   */
  private volatile int state;

注意:java并发包下有很多API都是基于AQS来实现加锁和解锁释放锁的功能的,AQS是java并发包的基础类,像ReentrantLock、ReentrantReadWriteLock底层都是基于AQS来实现的。

2 ReentrantLock加锁和释放锁的底层原理

给大家画一张图,可以让大家更好的理解AQS和ReentrantLock的关系。

 如图所示:ReentrantLock(还是JUC类中一些其他的并发类)中包含了AQS,ReentrantLock的加锁和解锁的功能就是依靠AQS来实现的。

假如此时有一个线程来用ReentrantLock进行lock()加锁。AOS内部有一个核心变量叫做state,并且用volatile修饰,初始值为0,并且AQS内部还有一个关键变量,用来记录当前加锁的是哪个线程,初始状态下,这个变量值null。

1)首先会用CAS操作将state从0变为1

注意:如果之前没有线程加过锁,才会加锁成功。否则会加锁失败,然后失败线程进入队列。

2)加锁线程会记录下当前线程的名字

 但是ReentrantLock是一个可重入锁,就是对于同一线程,可以进行多次加锁(必须是同一线程)。

如果线程1可重入加锁几次,会先判断一下当前线程是不是自己,那么state就会进行相应的累加,其它的不变。

但是此时又来了一个线程2怎么办呢?

此时如果来了一个线程2,发现state的状态不是0,线程1目前还没释放锁,state的状态依然是1。那么线程2的CAS失败会将自己放入等待队列。

总结:AQS的功能主要分为两类:独占和共享。它的所有子类中要么实现并使用了它的独占功能的API,要么使用了共享锁的功能。而不会同时使用两套API,即便是最有名的子类ReentrantReadWriteLock也是通过两个内部类读锁和写锁分别实现了两套api来实现的。

以上只是部分内容,为了维护方便,本文已迁移到新地址:AQS的初步了解 – 编程屋

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值