当前位置: 首页 > news >正文

深入剖析Java并发基石:AQS原理与实战

深入剖析Java并发基石:AQS原理与实战

一、为什么需要AQS?

在Java并发编程中,线程同步是保证数据一致性的核心挑战。JDK 1.5之前仅依赖synchronized关键字,存在灵活性差、功能单一等问题。Doug Lea设计的AQS框架,为ReentrantLockSemaphore等同步组件提供了统一底层支持,成为Java并发包的基石。


二、AQS核心设计思想

1. 核心结构
  • state状态变量
    32位整型值,通过volatile保证可见性。不同组件中含义不同:

    • ReentrantLock:表示重入次数
    • Semaphore:表示可用许可证数量
    • CountDownLatch:表示未完成的计数
  • CLH队列(FIFO双向链表)
    存储等待线程的队列,节点类型为Node,包含:

    volatile int waitStatus; // 节点状态(CANCELLED/SIGNAL/CONDITION等)
    volatile Node prev;      // 前驱节点
    volatile Node next;      // 后继节点
    Thread thread;           // 关联线程
    
2. 模板方法模式

AQS采用模板方法模式,将核心逻辑封装在acquire()release()等方法中,子类只需实现:

  • tryAcquire(int arg):尝试获取资源(独占模式)
  • tryRelease(int arg):尝试释放资源
  • tryAcquireShared(int arg):共享模式获取
  • tryReleaseShared(int arg):共享模式释放

三、两种同步模式详解

1. 独占模式(Exclusive)

ReentrantLock为例:

  • 加锁流程

    1. 线程调用lock()时,尝试通过tryAcquire()修改state(0→1)。
    2. 若失败,将线程封装为Node.SIGNAL节点加入队列尾部,通过LockSupport.park()阻塞。
    3. 当头部节点的后继节点被唤醒时,重新尝试获取锁。
  • 解锁流程

    1. 调用unlock()执行tryRelease()减少state
    2. state=0,唤醒后继节点中的线程。

重入性实现state记录重入次数,释放时需匹配调用次数。

2. 共享模式(Shared)

Semaphore为例:

  • 获取许可证

    1. acquire()调用tryAcquireShared()减少state(剩余许可证)。
    2. state<0,线程入队阻塞。
    3. 前驱节点释放时,唤醒连续多个共享节点(与独占模式区别)。
  • 释放许可证

    1. release()增加state,唤醒后续节点。
    2. 唤醒传播直至无资源可用。

四、关键源码流程剖析

1. acquire()方法流程(独占模式)
public final void acquire(int arg) {if (!tryAcquire(arg) &&      // 子类实现获取逻辑acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) // 加入队列selfInterrupt();
}
  • addWaiter():将线程包装为Node并插入队尾(CAS保证线程安全)。
  • acquireQueued()
    • 循环检查当前节点是否为头节点的后继(即“第二顺位”)。
    • 若符合条件则尝试tryAcquire(),成功后将自己设为新头节点。
    • 否则调用LockSupport.park()挂起线程。
2. 节点唤醒机制
  • 当头部节点释放锁时:
    1. 调用unparkSuccessor()找到离头节点最近的非取消状态节点。
    2. 通过LockSupport.unpark(node.thread)唤醒线程。

五、AQS在同步组件中的应用

组件同步模式state含义特性
ReentrantLock独占重入次数支持公平/非公平锁
Semaphore共享可用许可证数量可控制并发线程数
CountDownLatch共享未完成的任务数一次性屏障,不可重置
ReentrantReadWriteLock组合模式高16位读锁,低16位写锁读写分离,写锁优先

六、AQS的进阶特性

  1. 可中断与超时
    acquireInterruptibly()tryAcquireNanos()支持响应中断和超时控制。

  2. 条件变量(Condition)
    通过ConditionObject实现等待队列,与同步队列分离。

    • await():释放锁并加入条件队列。
    • signal():将条件队列节点转移到同步队列。
  3. 公平 vs 非公平锁

    • 公平锁:严格按队列顺序获取资源。
    • 非公平锁:新线程直接尝试插队(性能更高,可能引发饥饿)。

七、AQS的设计哲学与局限

优势
  • 解耦性:分离同步状态管理与线程排队逻辑。
  • 扩展性:基于模板方法支持多样化同步组件。
  • 性能优化:自旋+CAS减少上下文切换。
注意事项
  1. 子类需重写try*方法时保证线程安全(通常用CAS操作)。
  2. 避免在tryAcquire()中调用可能阻塞的操作。

适用场景:高并发锁、资源池管理、任务协调等。不适用于IO密集型阻塞操作。


总结

AQS通过state状态和CLH队列的协作,为Java并发提供了高效、灵活的底层支持。理解其工作原理,不仅能优化高并发程序设计,更是深入Java并发体系的必经之路。其设计思想(如模板方法、CAS自旋)在分布式锁等场景中亦有广泛应用。


文章转载自:
http://betake.zzgtdz.cn
http://alienate.zzgtdz.cn
http://acclivity.zzgtdz.cn
http://basseterre.zzgtdz.cn
http://baldric.zzgtdz.cn
http://agressire.zzgtdz.cn
http://casque.zzgtdz.cn
http://barware.zzgtdz.cn
http://abo.zzgtdz.cn
http://carpaccio.zzgtdz.cn
http://bathwater.zzgtdz.cn
http://apparat.zzgtdz.cn
http://bourgogne.zzgtdz.cn
http://celery.zzgtdz.cn
http://academism.zzgtdz.cn
http://buckhorn.zzgtdz.cn
http://almonry.zzgtdz.cn
http://arraign.zzgtdz.cn
http://bimester.zzgtdz.cn
http://berm.zzgtdz.cn
http://athenian.zzgtdz.cn
http://bionomy.zzgtdz.cn
http://carpometacarpus.zzgtdz.cn
http://blackbird.zzgtdz.cn
http://ballyrag.zzgtdz.cn
http://bribe.zzgtdz.cn
http://balefulness.zzgtdz.cn
http://ballerine.zzgtdz.cn
http://barbitone.zzgtdz.cn
http://aymaran.zzgtdz.cn
http://www.dtcms.com/a/281311.html

相关文章:

  • java 并发面试题2
  • 【Java篇】IntelliJ IDEA 安装与基础配置指南
  • Linux操作系统从入门到实战(十)Linux开发工具(下)make/Makefile的推导过程与扩展语法
  • 大模型在1型糖尿病肾病V期预测及治疗方案制定中的应用研究
  • 快速了解 HTTPS
  • MyBatis Plus功能增强全解析:从手写SQL到优雅开发的进阶指南
  • 16、鸿蒙Harmony Next开发:组件扩展
  • KeilMDK5如何生成.bin文件
  • 项目进度跨地域团队协作困难,如何统一进度安排
  • PHP语法高级篇(三):Cookie与会话
  • Redis中的红锁
  • ADC采集、缓存
  • Axios 完整功能介绍和完整示例演示
  • 映美打印机-URL页面打印
  • Spring MVC 执行流程详解:一次请求经历了什么?
  • 微信小程序:在ios中border边框显示不全
  • XCTF-repeater三链破盾:PIE泄露+ROP桥接+Shellcode执行的艺术
  • PyTorch 数据加载实战:从 CSV 到图像的全流程解析
  • 股指期货主连和次主连的区别是什么?
  • 游戏加速器核心技术:动态超发
  • Linux 文件系统实现层详解:原理、结构与驱动衔接
  • 人类气道黏膜下腺类器官:解析呼吸炎症与感染的新平台
  • Sharding-JDBC 分布式事务实战指南:XA/Seata 方案解析(三)
  • (3)从零开发 Chrome 插件:网页图片的批量下载
  • Google EMM是什么?
  • Git Idea 冲突解决
  • GitHub Pages无法访问以点号.开头的目录
  • 【实时Linux实战系列】实时数据流的网络传输
  • 百度移动开发面经合集
  • 【matlab】三维路面谱生成代码