栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

AQS的初步了解

Java 更新时间:发布时间: 百科书网 趣学号

目录

1 什么是AQS

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

1 什么是AQS

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

AQS依赖它来完成同步状态的管理(volatile修饰的state,用于标志是否持有锁)。如果获取同步状态state失败时,会将当前线程和等待信息构建成一个Node节点。将Node放到FIFO队列中,同时阻塞当前线程,当前线程同步状态state释放时,会把FIFO队列中的首节点唤醒,使其获取同步状态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的核心原理分析_Carry-wws的博客-CSDN博客_aqs的原理

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/986544.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号