Java AQS:JUC 并发体系的底层同步框架基石

本文涉及的产品
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: AQS(AbstractQueuedSynchronizer)是Java并发包(JUC)的底层核心,以volatile state + CLH双向队列统一实现同步控制。支持独占(如ReentrantLock)与共享(如Semaphore、CountDownLatch)两种模式,通过模板方法封装排队、阻塞/唤醒等通用逻辑,是理解与定制高性能同步组件的关键基石。(239字)

Java 开发中高频使用的 ReentrantLockCountDownLatchSemaphoreCyclicBarrier 等JUC并发工具,全部构建在同一个底层核心之上——AbstractQueuedSynchronizer(抽象队列同步器,简称AQS)。它是Doug Lea设计的通用同步框架,统一了JUC体系的同步实现逻辑,是Java并发进阶必须吃透的底层核心。

一、AQS的核心设计思想

AQS用极简的两个核心组件,解决了并发同步的两大根本问题:同步状态的原子管理竞争失败线程的排队与唤醒

  1. volatile修饰的int型state同步状态变量
    这是AQS的同步核心,所有线程对同步资源的抢占,本质都是对state变量的原子操作。volatile保证了state的多线程可见性,所有修改均通过CAS实现原子性,彻底规避了竞态问题。
  2. CLH双向链表实现的线程等待队列
    竞争state失败的线程,会被封装成Node节点加入这个双向队列,进入阻塞等待状态;当持有同步状态的线程释放资源时,会按队列顺序唤醒后继线程,实现公平的排队调度,避免了CPU空转与线程惊群效应。

二、两大核心工作模式

AQS基于模板方法模式设计,将线程排队、阻塞、唤醒等通用逻辑全部封装固化,开发者仅需实现少量try开头的模板方法,自定义state的获取与释放规则,即可快速实现自定义同步工具。它支持两种完全不同的同步模式,覆盖了几乎所有并发场景。

  1. 独占模式
    同一时间仅允许一个线程持有同步状态,典型实现是ReentrantLock。核心模板方法为tryAcquire(尝试获取独占资源)与tryRelease(尝试释放独占资源)。
    可重入锁的实现逻辑,就是在tryAcquire中判断当前线程是否为锁持有线程,若是则对state做累加,释放时递减至0才真正释放锁,整个逻辑完全由子类自定义,AQS不做任何限制。
  2. 共享模式
    同一时间允许多个线程持有同步状态,典型实现是CountDownLatchSemaphore。核心模板方法为tryAcquireSharedtryReleaseShared
    例如Semaphore就是将state作为许可总数,acquire时对state做减法,release时做加法,实现了限流的核心逻辑;CountDownLatch则是将state作为倒计时数,计数归0后唤醒所有等待线程。

三、底层核心优化细节

  1. 线程阻塞与唤醒机制
    AQS全程使用LockSupport.park()/unpark()实现线程的阻塞与唤醒,相比传统的wait/notify机制,它不会出现唤醒丢失问题——unpark()可以先于park()调用,提前为线程颁发运行许可,彻底规避了同步时序导致的线程永久阻塞问题。
  2. 节点等待状态管控
    队列中的每个Node节点都维护了waitStatus等待状态,标记线程的运行状态,核心包括SIGNAL(后继线程需要被唤醒)、CANCELLED(线程已取消等待)等,AQS通过状态精准控制线程的唤醒时机,避免无效的唤醒操作与CPU空耗。
  3. 公平与非公平调度原生支持
    AQS天然支持公平与非公平两种调度策略:公平锁在抢占资源前,会先检查等待队列是否有排队线程,有则直接进入队列排队;非公平锁则会直接通过CAS抢占资源,抢占失败再进入队列,这也是非公平锁吞吐量更高的核心原因。

四、核心认知误区与最佳实践

  • 常见误区1:AQS就是锁。真相:AQS是通用同步框架,锁只是它的一种应用场景,它还能实现倒计时门闩、信号量、栅栏、限流器等各类同步工具,适用范围远大于锁本身。
  • 常见误区2:AQS实现的锁性能不如synchronized。真相:JDK1.6+之后,基于AQS的ReentrantLock在高竞争长耗时场景下,性能优于升级到重量级的synchronized,同时还提供了可中断、超时获取、公平锁切换等更灵活的能力。
  • 常见误区3:AQS仅能用于JUC内置工具。真相:我们可以通过继承AQS,快速实现自定义高性能同步组件,比如分布式锁的本地排队层、自定义限流器、多线程协同屏障等,仅需实现对应的模板方法即可,无需重复开发线程排队等复杂逻辑。

结语

AQS是Java JUC并发体系的灵魂,它用极简的设计,将复杂的并发底层逻辑封装成通用能力,让开发者无需关注线程调度的细节,仅需聚焦业务同步规则的实现。理解AQS的底层原理,不仅能彻底搞懂JUC常用工具的实现逻辑,更是排查并发死锁、性能瓶颈,甚至实现自定义高性能同步组件的核心前提。

相关文章
|
1月前
|
存储 Java
java synchronized 锁升级:从偏向锁到重量级锁的底层自适应优化
`synchronized` 是Java核心同步机制,JDK 1.6起引入锁升级(无锁→偏向锁→轻量级锁→重量级锁),依托对象头Mark Word动态适配竞争强度,兼顾性能与稳定性,是并发编程必懂的底层逻辑。(239字)
245 8
|
1月前
|
网络协议 编译器 C语言
C语言深度解析:内存对齐与结构体填充的底层逻辑
C语言中,内存对齐是CPU硬件强制要求的底层规则,直接影响结构体大小、访问性能与硬件兼容性。合理排列成员可减少填充、节省内存;滥用`#pragma pack`则易致崩溃或性能暴跌。嵌入式、网络协议与跨平台开发必备核心知识。(239字)
286 14
|
1月前
|
XML Java 数据安全/隐私保护
彻底搞懂 Spring Boot 自动配置原理:从源码拆解到手写 Starter,零废话全干货
本文深入解析SpringBoot自动配置原理,基于SpringBoot 3.4.2版本详细拆解了自动配置的执行流程。主要内容包括:1)自动配置的本质是基于条件注解的动态JavaConfig配置类;2)核心执行流程通过AutoConfigurationImportSelector实现;3)SpringBoot 3.x采用新的自动配置注册方式;4)重点讲解了@Conditional系列条件注解的使用场景与常见坑点;5)通过开发自定义加密Starter实战演示完整实现过程。
653 3
|
8月前
|
缓存 Java Spring
Spring循环依赖:当两个Bean陷入鸡生蛋死循环时...
Spring中循环依赖问题常见于Bean相互依赖时,尤其在单例模式下。文章深入解析了循环依赖的成因及Spring的三级缓存解决方案,帮助理解Bean生命周期与依赖管理。
|
22天前
|
存储 网络协议 安全
C语言「内存对齐潜规则」:结构体里看不见的填充字节
内存对齐是CPU硬件要求的数据地址约束规则:变量须存于其字节大小的整数倍地址。编译器自动插入填充字节确保对齐,导致结构体体积“膨胀”、硬件寄存器读写错位或协议异常。合理排序成员(从大到小)、慎用`packed`、明确对齐控制,是嵌入式与底层开发的关键避坑要点。(239字)
|
SQL 关系型数据库 数据库
学习分布式事务Seata看这一篇就够了,建议收藏
学习分布式事务Seata看这一篇就够了,建议收藏
23826 2
|
1月前
|
存储 安全 编译器
C语言深度解析:变长数组(VLA)的底层逻辑与避坑指南
变长数组(VLA)是C99引入的栈上动态数组,长度运行时确定,访问快但无安全检查。易致栈溢出、野指针、跨平台兼容问题,仅适用于小尺寸、短生命周期场景,大数组务必用malloc。
317 38
|
28天前
|
存储 安全 编译器
C语言「存储期四象限」:变量生死的底层宪法,90%内存bug的根源
本文深入剖析C语言四大存储期(静态、自动、分配、线程),揭示“变量消失”“指针错乱”“内存泄漏”等顽疾的根源——**访问了生命周期已结束的内存**。用四象限模型厘清变量生死规则,助你从底层杜绝90%内存bug。(239字)
192 15
|
1月前
|
缓存 监控 Java
Java 四大引用体系:从GC回收规则到框架底层实现的完整真相
Java四大引用(强、软、弱、虚)是JDK1.2引入的核心内存管理机制,精准控制对象回收时机。强引用防回收,软引用保缓存(OOM前清理),弱引用防泄漏(GC即回收),虚引用唯一可靠跟踪回收——配合ReferenceQueue实现堆外内存释放等关键兜底。90%开发者仅知皮毛,实为解决OOM、内存泄漏及理解ThreadLocal/NIO底层的基石。(239字)
278 4
下一篇
开通oss服务