Java知识学习13(AQS详解)

news2024/11/29 8:53:12

1、AQS介绍?

AQS 的全称为 AbstractQueuedSynchronizer ,翻译过来的意思就是抽象队列同步器。这个类在 java.util.concurrent.locks 包下面。

AQS 就是一个抽象类,主要用来构建锁和同步器

public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable {
}

AQS 为构建锁和同步器提供了一些通用功能的实现,因此,使用 AQS 能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的 ReentrantLockSemaphore,其他的诸如 ReentrantReadWriteLockSynchronousQueue等等皆是基于 AQS 的。

2、AQS 原理?

AQS 核心思想AQS 核心思想是: 如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制 AQS 是基于 CLH 锁 (Craig, Landin, and Hagersten locks) 实现的。

CLH 锁是对自旋锁的一种改进,是一个虚拟的双向队列加粗样式(虚拟的双向队列即不存在队列实例,仅存在结点之间的关联关系),暂时获取不到锁的线程将被加入到该队列中。AQS 将每条请求共享资源的线程封装成一个 CLH 队列锁的一个结点(Node)来实现锁的分配。在 CLH 队列锁中,一个节点表示一个线程,它保存着线程的引用(thread)、 当前节点在队列中的状态(waitStatus)、前驱节点(prev)、后继节点(next)。

CLH 队列锁结构如下图所示:

在这里插入图片描述

AQS(AbstractQueuedSynchronizer)的核心原理图:
在这里插入图片描述

AQS 使用 int 成员变量 state 表示同步状态,通过内置的 线程等待队列 来完成获取资源线程的排队工作。

state 变量由 volatile 修饰,用于展示当前临界资源的获锁情况。

// 共享变量,使用volatile修饰保证线程可见性
private volatile int state;

另外,状态信息 state 可以通过 protected 类型的getState()、setState()compareAndSetState() 进行操作。并且,这几个方法都是 final 修饰的,在子类中无法被重写

//返回同步状态的当前值
protected final int getState() {
     return state;
}
 // 设置同步状态的值
protected final void setState(int newState) {
     state = newState;
}
//原子地(CAS操作)将同步状态值设置为给定值update如果当前同步状态的值等于expect(期望值)
protected final boolean compareAndSetState(int expect, int update) {
      return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}

ReentrantLock 为例,state 初始值为 0,表示未锁定状态。A 线程 lock() 时,会调用 tryAcquire() 独占该锁并将 state+1 。此后,其他线程再 tryAcquire() 时就会失败,直到 A 线程 unlock()state=0(即释放锁)为止,其它线程才有机会获取该锁。

当然,释放锁之前,A 线程自己是可以重复获取此锁的state 会累加),这就是可重入的概念。但要注意,获取多少次就要释放多少次,这样才能保证 state 是能回到零态的。

再以 CountDownLatch 以例,任务分为 N 个子线程去执行,state 也初始化为 N(注意 N 要与线程个数一致)。这 N 个子线程是并行执行的,每个子线程执行完后countDown() 一次,stateCAS(Compare and Swap) 减 1。等到所有子线程都执行完后(即 state=0 ),会 unpark() 主调用线程,然后主调用线程就会从 await() 函数返回,继续后余动作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/470525.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java学习17(IO模型详解)

1、何为IO? I/O(Input/Outpu) 即输入/输出 。 从计算机结构的角度来解读一下 I/O。 根据冯.诺依曼结构,计算机结构分为 5 大部分:运算器、控制器、存储器、输入设备、输出设备。 输入设备(比如键盘&am…

规模增长背后抖音如何构建直播体验优化

随着抖音直播用户持续增加,生态日渐丰富,在经历亿万规模化增长的过程之中,体验优化是必须要面对的问题,如何建立不同阶段的优化体系?如何抓住过程中的优化重点?另外面对业务增长诉求,面对新技术…

计算机网络学习08(TCP三次握手和四次挥手)

1、建立连接—TCP上次握手 建立一个 TCP 连接需要“三次握手”,缺一不可 : 一次握手: 客户端发送带有 SYN(SEQx) 标志的数据包 -> 服务端,然后客户端进入 SYN_SEND 状态,等待服务器的确认;二…

《PyTorch 深度学习实践》第13讲 循环神经网络(高级篇)

文章目录 1 这一讲任务2 相关解释3 代码 该专栏内容为对该视频的学习记录:【《PyTorch深度学习实践》完结合集】 专栏的全部代码、数据集和课件全放在个人GitHub了,欢迎自取。 1 这一讲任务 根据名字中的字符来预测其是哪个语言地区:如&quo…

03_线程间通信

面试题:两个线程打印 两个线程,一个线程打印1-52,另一个打印字母A-Z打印顺序为12A34B...5152Z,要求用线程间通信 public class Demo01 {public static void main(String[] args) {ShareData05 shareData05 new ShareData05();new…

DFIG控制11: 磁链定向矢量控制和仿真

DFIG控制11: 磁链定向矢量控制和仿真,主要是看下怎么根据DFIG模型来做矢量控制。 磁链定向和模型简化 原模型 dq同步坐标系下的模型:DFIG控制10: 双馈发电机的动态模型_Fantasy237的博客 电压方程: { u s d R s i…

AIhelp智能问答

前言 2023年,科技圈里,持续爆火的科技应用,毫无疑问是生成式AI,chatGPT了的,之所以令人惊叹,正是因为它的强大 可以这么认为,chatGPT能够解决很多问题,尤其是问答,问题答案的搜索,远比百度,google要精准,方便得多 如何提出高质量的问题,写好一个promot提示词,尤为重要,提出问题…

Anaconda+vscode+pytorch环境搭建

1、安装Anaconda ​ 不要添加到path,否则可能会引起其他冲突。 ​ 记得手动添加环境变量 2、安装vscode 已经不支持自定义安装啦,默认(D:\Program Files) 按住ctrlshiftp,输入language,选择第一个configure Display Language&…

TypeScript第一个程序HelloWorld

博主作品:《Java项目案例》主要基于SpringBootMyBatis/MyBatis-plusMySQLVue等前后端分离项目,可以在左边的分类专栏找到更多项目。《Uniapp项目案例》有几个有uniapp教程,企业实战开发。《微服务实战》专栏是本人的实战经验总结,…

新晋项目经理,如何快速胜任?

第一次当项目经理,往往会由于经验不足、项目管理知识的不足以及角色转换等原因,无从着手。 有时候我们会觉得一个项目经理,不像项目经理,那像什么呢?当然是像程序员。也就是说,他的职位虽然变化了&#x…

【MATLAB图像处理实用案例详解(16)】——利用概念神经网络实现手写体数字识别

目录 一、问题描述二、概念神经网络实现手写体数字识别原理三、算法步骤3.1 数据输入3.2 特征提取3.3 模型训练3.4 测试 四、运行结果 一、问题描述 手写体数字属于光学字符识别(Optical Character Recognition,OCR)的范畴,但分类…

07 【Sass语法介绍-控制指令】

1.前言 Sass 为我们提供了很多控制指令,使得我们可以更高效的来控制样式的输出,或者在函数中进行逻辑控制。本节内容我们就来讲解什么是 Sass 控制指令?它能用来做什么?它将使你更方便的编写 Sass 。 2.什么是 Sass 控制指令 控…

松下 OPF CMOS影像传感器

一、概述 不久前,松下在其国际网站公布了关于有机光电导膜(OPF)CMOS影像传感器技术的最新研发进展,并表示该技术已趋于成熟,有望在未来一段时间内正式投入商用。此外,松下还在3月15日至16日,于…

Oracle LiveLabs DB Security (数据库安全)实验汇总

在Oracle LiveLabs中,和数据库安全相关的实验分为2个系列,共12个实验。 Oracle数据库安全架构如下图: 这些实验涉及了Oracle安全相关的特性,企业版选件,独立产品和服务。 关于Oracle安全产品的中文主页可见&#…

Marior去除边距和迭代内容矫正用于自然文档矫正

一、简要介绍 本文简要介绍了论文**“ Marior: Margin Removal and Iterative Content Rectification for Document Dewarping in the Wild ”的相关工作。照相机捕捉到的文档图像通常会出现透视和几何变形。考虑到视觉美感较差和OCR系统性能下降,对其进行纠正具有重…

JavaScript实现输入圆的半径,输出周长、体积和面积的代码

以下为输入圆的半径,输出周长、体积和面积实现结果的代码和运行截图 目录 前言 一、请输入圆的半径,输出周长、体积和面积 1.1运行流程及思想 1.2代码段 1.3 JavaScript语句代码 1.4运行截图 前言 1.若有选择,您可以在目录里进行快速查找; 2.本博…

【crontab】如何解决命令末尾自动加^M,导致不生效的问题

目录 场景: 问题: 问题原因: 解决方案: Step 1:编辑文件yolov5 ,并查看文件类型 Step 2:修改文件类型 yolov5 Step 3:yolov5中的定时任务加入到crontab中,并查看crontab 列表…

前端性能优化总结(SPA篇)

性能优化 所有开发者都无法避免的一个问题,即关于项目的性能优化。性能优化是一个经久不衰的问题,它几乎贯穿于整个项目的开发过程。做好性能优化的项目不仅能在用户体验上更胜一筹,还能让服务资源的分配更加的合理。 关于SPA(单…

互联网医院开发|线上问诊系统开发|互联网医院功能开发

互联网医院在智慧医疗版块可以算的上是“核心成员”,无论是出色的实战能力还是在管理功能模块上,都为行业带来了切实的便利,就例如平时的工作安排,省时省力,也让患者有更方便的就医条件,互联网医院系统源码…

必须掌握的重写,重载,equals,==

生活是晨起暮落,日子是柴米油盐,时光匆匆,我们终将释怀。 重写与重载的区别 重写(Override) 1.发生在父类与子类之间 2.方法名,参数列表,返回类型必须相同 3.访问修饰符的限制一定要大于被重写方法的访问修饰符,如果…