【并发编程JUC】AQS详解
定义理解
AQS,全称为AbstractQueuedSynchronizer,是Java并发包(java.util.concurrent)中的一个框架级别的工具类,用于构建锁和同步器。它是许多同步类的基础,如ReentrantLock、Semaphore、CountDownLatch等,都是通过实现AQS的模板方法来实现其内部同步逻辑的。
- 同步状态:AQS使用一个volatile int类型的变量来表示同步状态,通过内置的FIFO(先进先出)队列(也称为CLH队列,一个虚拟的双向队列)来完成获取资源线程的排队工作。这个状态变量是线程共享的,用于表示同步资源的状态。
- CLH队列:CLH(Craig, Landin, and Hagersten)队列是AQS内部用于管理等待获取同步状态的线程的队列。它是一个虚拟的双向队列,即不存在队列实例,仅存在节点之间的关联关系。每个等待获取锁的线程都被封装成一个队列的节点(Node)。(将没有获取锁的线性封装成节点)

理解锁和同步器的关系
- 锁(Lock):锁是面向使用者的,它定义了使用者与锁交互的接口,比如允许两个线程并行访问某个资源,但隐藏了实现细节。锁是一个更高级的同步机制,它提供了比synchronized关键字更丰富的功能和灵活性。常见的锁实现有ReentrantLock等。
- 同步器(AbstractQueuedSynchronizer, AQS):同步器是面向锁的实现者的,它简化了锁的实现方式,屏蔽了同步状态管理、线程的排队、等待与唤醒等底层操作。同步器是构建锁和其他同步组件的基础框架,通过提供一套模板方法,使得开发者能够轻松地实现自定义的同步逻辑。
- 锁的实现依赖于同步器:在锁的实现中,通常会聚合同步器(AQS)来实现锁的语义。同步器为锁提供了必要的同步机制,如线程的排队、等待与唤醒等,从而简化了锁的实现复杂度。
AQS结构

梳理结构
- Lock是Java并发包(java.util.concurrent.locks)中的一个接口
- ReentrantLock是Lock接口的一个具体实现,它提供了可重入的互斥锁。
- Sync是ReentrantLock中的一个内部抽象类,它继承自AbstractQueuedSynchronizer(AQS)。
- FairSync是ReentrantLock中的一个内部类,它继承自Sync类。
- NonfairSync同样是ReentrantLock的一个内部类,也继承自Sync类
- AQS是Java并发包中的一个基础类,用于构建同步器(如锁和其他同步组件)。
Lock接口定义了锁的基本行为;ReentrantLock是Lock接口的一个具体实现,提供了可重入的互斥锁;Sync是ReentrantLock的内部抽象类,用于提供锁的基本实现机制;FairSync和NonfairSync是Sync的两个子类,分别实现了公平锁和非公平锁的逻辑;AQS则是ReentrantLock等同步器实现同步功能的基础。这些组件共同构成了Java并发包中强大的锁机制。
非公平锁源码如下:

公平锁源代码如下:


在非公平锁中,由于新到来的线程有可能直接尝试获取锁(而不需要排队),因此唤醒机制需要灵活处理。
模拟示例

假设有三个线程A、B、C都试图获取同一个ReentrantLock的锁(该锁以非公平模式配置)。

线程A的行为
- 尝试获取锁:线程A首先调用lock()方法,该方法内部会尝试通过compareAndSetState(0, 1)将锁的状态从0(未锁定)更改为1(锁定)。如果当前没有其他线程持有锁(即锁状态为0),则线程A成功获取锁。
- 执行业务逻辑:线程A在获取锁之后执行其业务逻辑。
线程B和C的行为(几乎同时)
当线程A持有锁时,线程B和C尝试获取锁。
- 调用acquire(1):线程B和C都调用acquire(1)方法,该方法是非公平锁获取锁的主要入口。
- 尝试非公平获取锁:acquire(1)内部调用tryAcquire(1),进而调用nonfairTryAcquire(1)。nonfairTryAcquire(1)首先检查当前锁状态是否为0(即未锁定),如果是,则尝试通过compareAndSetState(0, 1)获取锁。但由于线程A已经持有锁,所以B和C的这一步都会失败。(如果占用线程和当前线性为同一线程时,即为可重入锁)
- 添加等待者:由于nonfairTryAcquire(1)返回false,线程B和C都会调用addWaiter()方法将自己封装成一个节点(Node),并通过enq(node)方法将节点加入到等待队列中。如果队列为空(即还没有其他线程在等待),则初始化头节点(head)并设置尾节点(tail)为新加入的节点。否则,将新节点添加到队尾。
- 进入等待队列并等待:线程B和C在加入等待队列后,会调用acquireQueued(node, 1)方法。在这个方法中,线程会进入一个自旋循环,不断检查前驱节点的状态,并尝试通过park()方法使自己进入等待状态(阻塞)。如果前驱节点的状态是SIGNAL(-1),则线程会通过LockSupport.park(this)被阻塞,直到被唤醒。
线程A释放锁
- 释放锁:当线程A完成其业务逻辑后,会调用unlock()方法来释放锁。这会将锁的状态从1改回0,并唤醒等待队列中的一个线程(如果有的话)。
- 唤醒等待线程:在释放锁的过程中,unlock()方法会调用LockSupport.unpark(thread)来唤醒等待队列中的一个线程。由于是非公平锁,被唤醒的线程不一定是等待时间最长的线程(即队列的头部线程)。
线程B或C被唤醒
被唤醒的线程(可能是B也可能是C,这取决于线程调度器的决策)会重新进入acquireQueued(node, 1)方法的自旋循环,并再次尝试获取锁。如果此时锁已被释放(即状态为0),则该线程可能会成功获取锁并退出自旋循环,继续执行其业务逻辑。
相关文章:
【并发编程JUC】AQS详解
定义理解 AQS,全称为AbstractQueuedSynchronizer,是Java并发包(java.util.concurrent)中的一个框架级别的工具类,用于构建锁和同步器。它是许多同步类的基础,如ReentrantLock、Semaphore、CountDownLatch等…...
如何找BMS算法、BMS软件的实习
之前一直忙,好久没有更新了,今天就来写一篇文章来介绍如何找BMS方向的实习,以及需要具备哪些条件,我的实习经历都是在读研阶段找的,读研期间两段的实习经历再加上最高影响因子9.4分的论文,我的秋招可以说是…...
AR视频技术与EasyDSS流媒体视频管理平台:打造沉浸式视频体验
随着增强现实(AR)技术的飞速发展,其在各个领域的应用日益广泛。这项技术通过实时计算摄影机影像的位置及角度,将虚拟信息叠加到真实世界中,为用户带来超越现实的感官体验。AR视频技术不仅极大地丰富了我们的视觉体验&a…...
每天一个数据分析题(三百九十九)- 逻辑回归
逻辑回归中,若选0.5作为阈值区分正负样本,其决策平面是( ) A. wxb= 0 B. wxb= 1 C. wxb= -1 D. wxb= 2 数据分析认证考试介绍:点击进入 题目来源于CDA模拟题库 点…...
【ARMv8/v9 GIC 系列 5.2 -- GIC 分组介绍:Group 0 |Group 1| Non-Secure Group 1】
请阅读【ARM GICv3/v4 实战学习 】 文章目录 GIC Interrupt grouping中断分组配置寄存器GIC 中断分组介绍Group 0(安全组0)Group 1(安全组1)Non-Secure Group 1(非安全组1)总结及例子GIC Interrupt grouping ARM GICv3 通过中断分组机制,与ARMv8异常模型和安全模型进行…...
前端代码规范 - 日志打印规范
在前端开发中,随着项目迭代升级,日志打印逐渐风格不一,合理的日志输出是监控应用状态、调试代码和跟踪用户行为的重要手段。一个好的日志系统能够帮助开发者快速定位问题,提高开发效率。本文将介绍如何在前端项目中制定日志输出规…...
C# 类型转换之显式和隐式
文章目录 1、显式类型转换2. 隐式类型转换3. 示例4. 类型转换的注意事项5. 类型转换的应用示例总结 在C#编程中,类型转换是一个核心概念,它允许我们在程序中处理不同类型的数据。类型转换可以分为两大类:显式类型转换(Explicit Ca…...
Ubuntu多显示器设置不同缩放比例
Ubuntu多显示器设置不同缩放比例 设备问题解决方案 设备 笔记本屏幕分辨率为2560 \times 1600,外接显示器的分辨率为3840 \times 2160。 问题 Ubuntu默认的显示器设置中,缩放仅能选择100%,200%,300%,400%。假…...
以太网协议介绍——UDP
注:需要先了解一些以太网的背景知识,方便更好理解UDP协议、 以太网基础知识一 以太网基础知识二 UDP协议 UDP即用户数据报协议,是一种面向无连接的传输层协议,属于 TCP/IP 协议簇的一种。UDP具有消耗资源少、通信效率高等优点&a…...
FFMpeg rtmp 无压缩推送本地yuv文件 压缩推送本地yuv文件
可以借鉴的:C使用FFmpeg实现YUV数据编码转视频文件_C 语言_脚本之家 yuv文件下载地址:YUV Sequences 无压缩的方式推送本地yuv文件 代码: #include <stdio.h> #include <unistd.h> #include <iostream> extern "C&…...
PostgreSQL LIMIT 子句
PostgreSQL LIMIT 子句 PostgreSQL 是一种功能强大的开源对象关系数据库管理系统,广泛用于各种应用中。在处理大量数据时,我们通常只需要检索部分记录,而不是整个数据集。这时,LIMIT 子句就变得非常有用。本文将详细介绍 Postgre…...
误删分区后的数据拯救:双管齐下恢复策略
在数字化时代,数据的价值日益凸显,而误删分区作为常见的数据安全威胁之一,常常让用户措手不及。本文将深入探讨误删分区的现象,并为您揭示两种高效的数据恢复方案,旨在帮助您在最短时间内找回失去的数据,同…...
git 添加本地分支, clean
//以develop为源创建本地分支fromdevelop git checkout -b fromdevelop git add . git commit -m "local" git checkout -b local/dev //切换到远程分支. git checkout dev git clean_git clean -f -d-CSDN博客 git clean -f -d #删除当前目录下没有被track…...
Linux:进程间通信(一.初识进程间通信、匿名管道与命名管道、共享内存)
上次结束了基础IO:Linux:基础IO(三.软硬链接、动态库和静态库、动精态库的制作和加载) 文章目录 1.认识进程间通信2.管道2.1匿名管道2.2pipe()函数 —创建匿名管道2.3匿名管道的四种情况2.4管道的特征 3.基于管道的进程池设计4.命…...
QML-各类布局
Colunm布局 Column{id:colspacing: 30Repeater{id:repmodel: ListModel{}Button{width: 100height: 50text: "btn"index}}//开始时候移动move: Transition {NumberAnimation { properties: "x,y"; easing.type: Easing.OutBounce }}//添加时变化add:Transi…...
el-table封装点击列筛选行数据功能,支持筛选,搜索,排序功能
数据少的话,可以前端实现,如果多的话,建议还是请求接口比较合理父组件: <template> <div class"home"> <!-- <img alt"Vue logo" src"../assets/logo.png"> <HelloWorld …...
【SpringBoot3学习 | 第1篇】SpringBoot3介绍与配置文件
文章目录 前言 一. SpringBoot3介绍1.1 SpringBoot项目创建1. 创建Maven工程2. 添加依赖(springboot父工程依赖 , web启动器依赖)3. 编写启动引导类(springboot项目运行的入口)4. 编写处理器Controller5. 启动项目 1.2 项目理解1. 依赖不需要写版本原因2. 启动器(Starter)3. Sp…...
SpringBoot整合Dubbo的快速使用教程
目录 一、什么是Dubbo? 二、SpringBoot整合Dubbo 1、父工程引入依赖 2、各个Dubbo服务子模块引入依赖 3、服务提供者 (1)启动类添加注解EnableDubbo (2)服务类添加注解DubboService (3)配置文件…...
昇思25天学习打卡营第12天| 基于MindNLP+MusicGen生成自己的个性化音乐
之前都是看图文类的东西,今天体验一点不一样的。来点听力的内容。 mindspore有音乐生成模型MusicGen,MusicGen支持两种生成模式:贪心(greedy)和采样(sampling)。在实际执行过程中,采…...
代理设计模式和装饰器设计模式的区别
代理设计模式: 作用:为目标(原始对象)增加功能(额外功能,拓展功能) 三种经典应用场景: 1:给原始对象增加额外功能(spring添加事务,Mybatis通过代理实现缓存功能等等) 2:远程代理(网络通信,输出传输(RPC,D…...
AI Agent在智能风控中的实战:多智能体欺诈检测与预警
AI Agent在智能风控中的实战:多智能体欺诈检测与预警 你有没有过明明是正常交易却被银行冻结账户的糟糕体验?或是听说过某电商平台上线新活动首日就被黑产团伙薅走数千万补贴的新闻?随着黑产欺诈向团伙化、专业化、动态化演进,传统依赖规则引擎、单模型机器学习的风控体系已…...
软阴影:那个让虚拟世界“温柔起来“的光影小秘密
一、从一只小猫的影子说起 前几天我在朋友家做客,他家养了一只胖乎乎的橘猫,正趴在阳台的窗边晒太阳。我无意间瞥了一眼那只猫脚边的影子,突然被一个细节震撼了—— 那只猫的影子——并不是一片均匀的黑。 仔细看——猫肚子紧贴地板的地方——…...
亚马逊 Rufus 关停,Alexa 正式上线:卖家必须读懂的6条新规则
2026年5月13日,亚马逊官方正式宣布,下线Rufus,推出全新AI购物助手:Alexa for Shopping。但是,这不是粗暴地直接下线 Rufus,而是一次购物AI底层架构的重组 —— 将 Rufus 的商品专长 与 Alexa的用户理解力&a…...
潮州东方轻奢风全屋高定找哪家
开篇引言根据《2026年中国全屋定制行业发展报告》,潮州市全屋定制市场规模同比增长38%,其中全屋高端定制细分市场同比增长52%。目前,潮州市家庭全屋定制需求占比72%,高端定制需求占比45%。为了帮助潮州市消费者选择合规、靠谱、差…...
WebSocket实时通信架构进阶:Room、命名空间与集群部署
WebSocket实时通信架构进阶:Room、命名空间与集群部署 作者:Crown_22 | AI Agent & Hermes Agent 桌面程序开发者 前言 WebSocket已经成为实时应用的标准技术,但大多数教程只停留在"建立连接、发送消息"的基础阶段。在生产环境中,你需要处理Room管理、命名空…...
免费抓包工具选型指南:Wireshark、Fiddler、mitmproxy、Charles实战对比
1. 抓包工具不是“黑科技”,而是网络世界的显微镜很多人第一次听说“抓包”,脑子里立刻浮现出黑客电影里满屏滚动的绿色代码、键盘敲得噼啪作响、三秒破解银行防火墙的画面。其实完全不是这样——抓包(Packet Capture)本质上就是把…...
保姆级教程:在Windows 10上用QEMU+Kylin搭建可内外网访问的完整开发环境
在Windows 10上构建QEMUKylin全功能开发环境的终极指南当开发者需要在本地快速搭建一个隔离的国产操作系统开发环境时,QEMU虚拟化方案配合银河麒麟系统能提供高度灵活的沙箱体验。本文将手把手带你完成从零配置到内外网联通的完整工作流,涵盖虚拟化环境部…...
学习日志(三)【php语法学习,iscc校赛wp】
1. 任务 1.1.1.1.1.1. 知识部分 rce看【之前的笔记?】php的知识点学习继续jwt token好像是比赛的题目考察内容,我看看php伪协议 1.1.1.1.1.2. 题目 参加iscc比赛【五一】rce题目 1.1.1.1.1.3. 环境配置 把vscode搞好,上学期没有把Php配…...
招行+工行:ReAct(Reasoning + Acting) 讲清楚,并结合 金融场景(含自进化智能体) 给出可直接用的案例
下面我把 ReAct(Reasoning Acting) 讲清楚,并结合 ** 金融场景(含自进化智能体)** 给出可直接用的案例与话术,适合分享 / 汇报。一、ReAct 是什么(一句话)ReAct 推理(T…...
正视孩童情绪波动,耐心陪伴平稳疏导
孩子的情绪就像夏天的天气,前一秒还晴空万里,后一秒可能就乌云密布。面对突如其来的哭闹、发脾气或者闷闷不乐,很多家长会急着“灭火”——要么讲道理,要么直接制止。但其实,情绪波动本身不是问题,它是孩子…...
