当前位置:网站首页>12、AbstractQueuedSynchronizer之AQS
12、AbstractQueuedSynchronizer之AQS
2022-06-11 12:07:00 【施小赞】
1、前置知识
2、是什么
2.1、字面意思
AbstractQueuedLongSynchronizer
AbstractQueuedSynchronizer 通常地:AbstractQueuedSynchronizer简称为AQS
2.2、技术解释
是用来构建锁或者其它同步器组件的重量级基础框架及整个JUC体系的基石,通过内置的FIFO队列来完成资源获取线程的排队工作,并通过一个int类变量表示持有锁的状态
CLH:Craig、Landin and Hagersten 队列,是一个单向链表,AQS中的队列是CLH变体的虚拟双向队列FIFO
3、AQS为什么是JUC内容中最重要的基石
3.1、和AQS有关的
3.2、进一步理解锁和同步器的关系
定义了程序员和锁交互的使用层API,隐藏了实现细节,你调用即可。
比如Java并发大神DougLee,提出统一规范并简化了锁的实现,
4、能干嘛
4.1、加锁会导致阻塞
4.2、解释说明
抢到资源的线程直接使用处理业务,抢不到资源的必然涉及一种 排队等候机制 。抢占资源失败的线程继续去等待(类似银行业务办理窗口都满了,暂时没有受理窗口的顾客只能去 候客区排队等候 ),但等候线程仍然保留获取锁的可能且获取锁流程仍在继续(候客区的顾客也在等着叫号,轮到了再去受理窗口办理业务)。
既然说到了 排队等候机制 ,那么就一定会有某种队列形成,这样的队列是什么数据结构呢?
如果共享资源被占用, 就需要一定的阻塞等待唤醒机制来保证锁分配 。这个机制主要用的是CLH队列的变体实现的,将暂时获取不到锁的线程加入到队列中,这个队列就是AQS的抽象表现。它将请求共享资源的线程封装成队列的结点( Node ),通过CAS、自旋以及LockSupport.park()的方式,维护state变量的状态,使并发达到同步的效果。
5、AQS初步
5.1、AQS初识
AQS使用一个volatile的int类型的成员变量来表示同步状态,通过内置的FIFO队列来完成资源获取的排队工作将每条要去抢占资源的线程封装成一个Node节点来实现锁的分配,通过CAS完成对State值的修改。
5.2、AQS内部体系架构
5.2.1、AQS自身
static final class Node{
//共享
static final Node SHARED = new Node();
//独占
static final Node EXCLUSIVE = null;
//线程被取消了
static final int CANCELLED = 1;
//后继线程需要唤醒
static final int SIGNAL = -1;
//等待condition唤醒
static final int CONDITION = -2;
//共享式同步状态获取将会无条件地传播下去
static final int PROPAGATE = -3;
// 初始为0,状态是上面的几种
volatile int waitStatus;
// 前置节点
volatile Node prev;
// 后继节点
volatile Node next;
// 当前Node线程
volatile Thread thread;
//指向下一个处于CONDITION 状态的节点
Node nextWaiter;
// ...
5.3、AQS同步队列的基本结构
CLH:Craig、Landin and Hagersten 队列,是个单向链表,AQS中的队列是CLH变体的虚拟双向队列(FIFO)
6、从我们的ReentrantLock开始解读AQS
Lock接口的实现类,基本都是通过【聚合】了一个【队列同步器】的子类完成线程访问控制的
可以明显看出公平锁与非公平锁的lock()方法唯一的区别就在于公平锁在获取同步状态时多了一个限制条件:
hasQueuedPredecessors是公平锁加锁时判断等待队列中是否存在有效节点的方法
对比公平锁和非公平锁的 tryAcquire()方法的实现代码,其实差别就在于 非公平锁获取锁时比公平锁中少了一个判断 !hasQueuedPredecessors()
hasQueuedPredecessors() 中判断了是否需要排队,导致公平锁和非公平锁的差异如下:
公平锁 :公平锁讲究先来先到,线程在获取锁时,如果这个锁的等待队列中已经有线程在等待,那么当前线程就会进入等待队列中;
非公平锁 :不管是否有等待队列,如果可以获取锁,则立刻占有锁对象。也就是说队列的第一个排队线程在unpark(),之后还是需要竞争锁(存在线程竞争的情况下)
双向链表中,第一个节点为虚节点(也叫哨兵节点),其实并不存储任何信息,只是占位。
acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
shouldParkAfterFailedAcquire 和 parkAndCheckInterrupt 方法中
如果前驱节点的 waitStatus 是 SIGNAL状态,即 shouldParkAfterFailedAcquire 方法会返回 true 程序会继续向下执行 parkAndCheckInterrupt 方法,用于将当前线程挂起
边栏推荐
- [Chapter II Relationship between genes and chromosomes] summary of biological knowledge - Biology in grade one of senior high school
- JMeter 学习心得
- 深度学习与CV教程(14) | 图像分割 (FCN,SegNet,U-Net,PSPNet,DeepLab,RefineNet)
- 近期使用nodejs pinyin包时遇到的问题
- 线程五种状态(线程生命周期)
- Splunk Bucket 背后的秘密
- flink 数据流图、并行度、算子链、JobGraph与ExecutionGraph、任务和任务槽
- 微信web开发者,如何学习web开发
- 刷题笔记(十四)--二叉树:层序遍历和DFS,BFS
- typescript 编译选项和配置文件
猜你喜欢

C# 读取txt文件生成Word文档

Uncaught typeerror: cannot set property 'next' of undefined

centos安装mysql5.7

一些比较的常用网站

flink Window Join、Interval Join、Window CoGroup (两流匹配 指定key联结,开窗口进行窗口操作)

Iframe value transfer

Is the SSL certificate reliable in ensuring the information security of the website?

13、ReentrantLock、ReentrantReadWriteLock、StampedLock讲解

Intl.numberformat set number format

Error occurred when MySQL imported the database data in pagoda as 0000-00-00 and enum as null
随机推荐
Splunk 手工同步search head
Specflow环境搭建
flink 控制窗口行为(触发器、移除器、允许延迟、将迟到的数据放入侧输出流)
Notes on brushing questions (13) -- binary tree: traversal of the first, middle and last order (review)
一般运维架构图
Apple mobileone: the mobile terminal only needs 1ms of high-performance backbone
C # apply many different fonts in PDF documents
Is reflection really time-consuming? How long does it take to reflect 100000 times.
Centos7.x下安装mysql8遇到的问题Couldn‘t open file /etc/pki/rpm-gpg/RPM-GPG-KEY-mysql-2022
Sulley fuzzer learning
Zhejiang University and Microsoft Asia Research Institute released a new method of video recognition, which can recognize video frame by frame without data marking, or can be used for sign language tr
Is the SSL certificate reliable in ensuring the information security of the website?
When the security engineer finds a major vulnerability in the PS host, the CD can execute arbitrary code in the system
合并两个有序数组(C语言)
Elk - x-pack set user password
Objectinputstream read file object objectoutputstream write file object
[JUC supplementary] immutable object, shared meta mode, final principle
Uncaught typeerror: cannot set property 'next' of undefined
Splunk Bucket 背後的秘密
centos安装mysql5.7






























