发布时间:2026/8/21 14:37:33
AQS学习 1. AQS 简介1.1 什么是 AQSAQSAbstractQueuedSynchronizer是 Java 并发包java.util.concurrent.locks中的一个核心框架类用于构建锁和其他同步器。AQS 是一个用来构建锁和同步器的框架使用 AQS 能简单且高效地构造出应用广泛的大量的同步器。常见的同步器如ReentrantLock、Semaphore、ReentrantReadWriteLock、SynchronousQueue、FutureTaskJDK 1.7等都是基于 AQS 实现的。开发者也可以利用 AQS 轻松构造符合自己需求的同步器。2. AQS 核心原理2.1 核心思想AQS 的核心思想是如果被请求的共享资源空闲则将当前请求资源的线程设置为有效的工作线程并将共享资源设置为锁定状态。如果被请求的共享资源被占用则需要一套线程阻塞等待以及被唤醒时锁分配的机制。这个机制 AQS 是用 CLH 队列锁实现的即将暂时获取不到锁的线程加入到队列中。2.2 CLH 队列详解关于 AQS 类的 CLH 队列源码注释中有详细说明Wait queue node class. The wait queue is a variant of a CLH (Craig, Landin, and Hagersten) lock queue. CLH locks are normally used for spinlocks. We instead use them for blocking synchronizers, but use the same basic tactic of holding some of the control information about a thread in the predecessor of its node. A status field in each node keeps track of whether a thread should block. A node is signalled when its predecessor releases. Each node of the queue otherwise serves as a specific-notification-style monitor holding a single waiting thread. The status field does NOT control whether threads are granted locks etc though. A thread may try to acquire if it is first in the queue. But being first does not guarantee success; it only gives the right to contend. So the currently released contender thread may need to rewait. To enqueue into a CLH lock, you atomically splice it in as new tail. To dequeue, you just set the head field.2.2.1 主要含义等待队列节点类。等待队列是CLHCraig、Landin和Hagersten锁定队列的变体。CLH锁通常用于自旋锁。AQS 使用它们来实现阻塞同步器但采用相同的基本策略在其前驱节点中保存有关线程的控制信息。每个节点中的状态字段跟踪线程是否应该阻塞。节点在其前驱释放时收到信号。队列的每个节点充当一个特定通知样式的监视器保存一个等待线程。状态字段不控制线程是否被授予锁等。如果线程是队列中的第一个则可以尝试获取锁但这不保证成功只赋予竞争的权利。入队到 CLH 锁只需要对tail执行一个原子操作出队只需要更新head字段。2.2.2 CLH 队列结构------ prev ----- ----- head | | ---- | | ---- | | tail ------ ----- -----2.2.3 插入与删除机制Insertion into a CLH queue requires only a single atomic operation on tail, so there is a simple atomic point of demarcation from unqueued to queued. Similarly, dequeuing involves only updating the head. However, it takes a bit more work for nodes to determine who their successors are, in part to deal with possible cancellation due to timeouts and interrupts. The prev links (not used in original CLH locks), are mainly needed to handle cancellation. If a node is cancelled, its successor is (normally) relinked to a non-cancelled predecessor. For explanation of similar mechanics in the case of spin locks, see the papers by Scott and Scherer at http://www.cs.rochester.edu/u/scott/synchronization/ We also use next links to implement blocking mechanics. The thread id for each node is kept in its own node, so a predecessor signals the next node to wake up by traversing next link to determine which thread it is. Determination of successor must avoid races with newly queued nodes to set the next fields of their predecessors. This is solved when necessary by checking backwards from the atomically updated tail when a nodes successor appears to be null. (Or, said differently, the next-links are an optimization so that we dont usually need a backward scan.)翻译插入 CLH 队列只需要对尾部执行一个原子操作所以从未排队到排队有一个简单的原子分界点。同样退出队列只涉及更新头部。然而节点需要更多的工作来确定它们的后继者是谁部分原因是要处理由于超时和中断而可能导致的取消。prev链接未在原始 CLH 锁中使用主要用于处理取消。如果某个节点被取消则其后续节点通常将重新链接到未取消的前驱节点。还使用next链接来实现阻塞机制。每个节点的线程 ID 都保存在自己的节点中因此前驱节点通过遍历下一个链接来通知下一个节点唤醒以确定它是哪个线程。确定后继节点必须避免与新排队的节点竞争以设置前驱的next字段。2.2.4 取消机制与条件队列Cancellation introduces some conservatism to the basic algorithms. Since we must poll for cancellation of other nodes, we can miss noticing whether a cancelled node is ahead or behind us. This is dealt with by always unparking successors upon cancellation, allowing them to stabilize on a new predecessor, unless we can identify an uncancelled predecessor who will carry this responsibility. CLH queues need a dummy header node to get started. But we dont create them on construction, because it would be wasted effort if there is never contention. Instead, the node is constructed and head and tail pointers are set upon first contention. Threads waiting on Conditions use the same nodes, but use an additional link. Conditions only need to link nodes in simple (non-concurrent) linked queues because they are only accessed when exclusively held. Upon await, a node is inserted into a condition queue. Upon signal, the node is transferred to the main queue. A special value of status field is used to mark which queue a node is on. Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill Scherer and Michael Scott, along with members of JSR-166 expert group, for helpful ideas, discussions, and critiques on the design of this class.翻译取消给基本算法引入了一些保守性。由于必须轮询其他节点的取消因此可能无法注意到被取消的节点是在我们之前还是之后。这是通过在取消时始终取消后续节点的标记来解决的允许它们稳定在一个新的前驱节点上除非能够确定一个未被取消的前驱节点将承担此责任。CLH 队列需要一个虚拟头节点才能启动。但不会在构造时创建它们因为如果不存在争用这将浪费精力。相反在第一次争用时构造节点并设置头指针和尾指针。等待条件的线程使用相同的节点但使用额外的链接。条件只需要链接简单非并发链接队列中的节点因为它们只在独占时被访问。等待时节点被插入到条件队列中。发出信号后节点被转移到主队列。状态字段的特殊值用于标记节点所在的队列。3. AQS 核心组件3.1 同步状态StateAQS 使用一个 int 成员变量来表示同步状态通过内置的 FIFO 队列来完成获取资源线程的排队工作。AQS 使用 CAS 对该同步状态进行原子操作实现对其值的修改。3.2 状态操作方法状态信息通过 protected 类型的getState()、setState()、compareAndSetState()进行操作getState()获取当前同步状态setState(int newState)设置当前同步状态compareAndSetState(int expect, int update)使用 CAS 设置当前状态保证原子性4. 总结AQS 是 Java 并发编程的基石通过 CLH 队列和状态管理机制为各种同步器提供了统一的实现框架。理解 AQS 的工作原理对于深入掌握 Java 并发编程至关重要。

相关新闻

2026/8/21 14:32:33

124、洞察驱动的实战标题——HDR+的“对齐vs融合“——Google HDR+的对齐策略与暴力融合的差异,如何用多尺度光流实现亚像素对齐

124、洞察驱动的实战标题——HDR+的"对齐vs融合"——Google HDR+的对齐策略与暴力融合的差异,如何用多尺度光流实现亚像素对齐 上周在调试一台国产旗舰机的夜景HDR时,我盯着屏幕上的鬼影看了整整三个小时。那是一个典型的动态场景——霓虹灯牌下有人走过,远处有车…

2026/8/21 17:27:55

WebTorrent.IO:零安装,在浏览器里播放BT种子

WebTorrent.IO:零安装,在浏览器里播放BT种子 【免费下载链接】webtorrent.io The code that runs the WebTorrent website 项目地址: https://gitcode.com/gh_mirrors/we/webtorrent.io 想直接看一个种子文件,过去得先装下载客户端&am…

2026/8/21 17:22:54

WinCDEmu一学就会:免费虚拟光驱把ISO镜像秒变可用光盘

WinCDEmu一学就会:免费虚拟光驱把ISO镜像秒变可用光盘 【免费下载链接】WinCDEmu 项目地址: https://gitcode.com/gh_mirrors/wi/WinCDEmu 周末深夜,小林从储物箱底翻出一张十年前的经典游戏光盘,想重温一下青春。可惜盘面早已布满划…

2026/8/21 13:13:49

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/20 20:11:18

工业传感器与变送器详解:序章 从物理世界到工业数据

序章 从物理世界到工业数据 ——重新认识工业传感器与变送器 工业自动化系统正变得日益复杂。今天的工业现场早已不是简单的控制回路,而是由多层技术共同构成的立体体系:PLC、DCS、SCADA、MES、工业互联网、边缘计算与人工智能。控制系统可以执行复杂算法,工业网络可以实现…

2026/8/21 0:03:13

Linux命令-uucico(UUCP传输程序)

Linux命令-uucico(UUCP传输程序) 🔰简介UUCP 体系简介 📖语法⚙️选项配置文件 💡示例示例 1:基本传输操作示例 2:主模式与从模式示例 3:调试与故障排查示例 4:UUCP 配置…

2026/8/21 0:03:13

Linux命令-uupick(UUCP文件接收工具)

Linux命令-uupick(UUCP文件接收工具)🔰简介uupick 在 UUCP 传输链中的位置📖语法⚙️选项交互命令💡示例示例 1:基本接收操作示例 2:仅处理来自特定系统的文件示例 3:完整 UUCP 文件…

2026/8/21 15:40:01

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/21 15:40:01

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/21 0:31:27

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…