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

Java AQS(AbstractQueuedSynchronizer)详解

Java AQS(AbstractQueuedSynchronizer)详解

AQS(AbstractQueuedSynchronizer) 是 Java 并发包(java.util.concurrent.locks)的核心基础框架,用于构建锁和其他同步器。ReentrantLock、Semaphore、CountDownLatch 等同步工具均基于 AQS 实现。


一、核心设计思想
  1. 状态管理
    通过 volatile int state 表示同步状态(如锁的重入次数、信号量的许可数)。

    private volatile int state; // 关键状态变量
    

    提供原子操作修改状态:

    protected final boolean compareAndSetState(int expect, int update) {// CAS 操作更新 state
    }
    
  2. 等待队列(CLH 变体)

    • 双向链表(FIFO)管理阻塞线程。
    • 节点类型:
      • EXCLUSIVE(独占模式,如 ReentrantLock)
      • SHARED(共享模式,如 Semaphore)

二、核心结构
// 队列节点定义
static final class Node {volatile int waitStatus;      // 节点状态(CANCELLED、SIGNAL、CONDITION等)volatile Node prev;          // 前驱节点volatile Node next;          // 后继节点volatile Thread thread;      // 关联的线程Node nextWaiter;             // 条件队列或共享模式标记
}

等待状态值

  • CANCELLED (1):线程已取消
  • SIGNAL (-1):后继节点需被唤醒
  • CONDITION (-2):线程在条件队列中等待
  • PROPAGATE (-3):共享模式下传播唤醒

三、工作模式
  1. 独占模式(Exclusive)

    • 加锁流程

      public final void acquire(int arg) {if (!tryAcquire(arg) &&          // 子类实现尝试获取锁acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) // 加入队列并阻塞selfInterrupt();
      }
      
      • tryAcquire():由子类实现(如 ReentrantLock 中判断重入)
      • addWaiter():将线程包装为节点加入队尾
      • acquireQueued():自旋或阻塞等待唤醒
    • 解锁流程

      public final boolean release(int arg) {if (tryRelease(arg)) {           // 子类实现释放锁Node h = head;if (h != null && h.waitStatus != 0)unparkSuccessor(h);     // 唤醒后继节点return true;}return false;
      }
      
  2. 共享模式(Shared)

    • 用于信号量、CountDownLatch 等。
    • 核心方法:acquireShared() / releaseShared()
    • 与独占模式区别:唤醒时传播唤醒后续共享节点(如 PROPAGATE 状态)。

四、关键模板方法

子类必须实现的方法:

方法作用
boolean tryAcquire(int)独占模式获取锁
boolean tryRelease(int)独占模式释放锁
int tryAcquireShared(int)共享模式获取锁(返回剩余许可数)
boolean tryReleaseShared(int)共享模式释放锁
boolean isHeldExclusively()当前线程是否独占资源

五、自定义锁示例(不可重入锁)
public class SimpleLock extends AbstractQueuedSynchronizer {@Overrideprotected boolean tryAcquire(int arg) {if (compareAndSetState(0, 1)) { // CAS 修改 state: 0->1setExclusiveOwnerThread(Thread.currentThread()); // 设置独占线程return true;}return false;}@Overrideprotected boolean tryRelease(int arg) {if (getState() == 0) throw new IllegalMonitorStateException();setExclusiveOwnerThread(null); // 清除独占线程setState(0); // 状态重置为0return true;}public void lock() {acquire(1); // 调用AQS的独占获取}public void unlock() {release(1); // 调用AQS的独占释放}
}

六、AQS 在 JUC 中的应用
同步器实现原理
ReentrantLock独占模式 + state 记录重入次数
Semaphore共享模式 + state 表示许可数
CountDownLatch共享模式 + state 表示计数
ReentrantReadWriteLock读锁共享 + 写锁独占

七、高级特性
  1. 条件变量(Condition)

    • 通过 ConditionObject 实现(内部维护条件队列)。
    • await():释放锁并进入条件队列。
    • signal():将节点从条件队列移到同步队列。
  2. 中断处理

    • acquireInterruptibly():支持响应中断的获取锁。

八、总结
  • 核心价值:提供统一的线程排队、阻塞/唤醒机制。
  • 关键优势:子类只需关注状态管理逻辑(tryAcquire/tryRelease)。
  • 适用场景:构建高性能、可扩展的同步器。

提示:理解 AQS 是掌握 Java 并发编程的关键!建议结合源码(如 ReentrantLock)深入分析队列操作和状态转换。

http://www.lryc.cn/news/578869.html

相关文章:

  • 【前端】基础 - HTML基础标签和样式设置
  • Baumer工业相机堡盟工业相机如何实现高精度的硬件同步触发
  • 公用LCU屏的功能、应用场景
  • 微信小程序使用wx.chooseImage上传图片时进行压缩,并添加时间水印
  • 微信小程序入门实例_____打造你的专属单词速记小程序
  • PH热榜 | 2025-07-02
  • zabbix批量生成监控项教程!
  • Benchmarking in Go
  • 利器:NPM和YARN及其他
  • SQL Server 再进阶:类型多样性分析与时间维度扩展(第三课)
  • 解锁医疗AI密码:医疗人工智能专业大学四年学习路径
  • android核心技术摘要
  • 数论基础知识和模板
  • 香港券商交易系统开发与解决方案全景报告:云原生、跨境协同与高性能架构的创新实践
  • 【unitrix】 4.13 类型级加一计算(add1.rs)
  • 【GHS】Green Hills软件MULTI-IDE的安装教程
  • 【AI落地应用实战】AIGC赋能职场PPT汇报:从效率工具到辅助优化
  • Javaee 多线程 --进程和线程之间的区别和联系
  • Hadoop集群启动 (ZooKeeper、HDFS、YARN、Hbase)
  • 【网络】Linux 内核优化实战 - net.core.netdev_budget_usecs
  • VSCode-Copilot的系统提示词
  • mac mini m4安装node.js@16以下版本方法
  • Linux下MinIO分布式安装部署
  • REST API设计与Swagger:构建高效、易用的Web服务
  • 如何设置电脑定时休眠?操作指南详解
  • STM32 使用 TinyUSB
  • 【leetcode算法300】:哈希板块
  • 【RTSP从零实践】6、实现最简单的同时传输H264、AAC的RTSP服务器
  • SpringCloud系列(46)--SpringCloud Bus实现动态刷新全局广播
  • 免费版安全性缩水?ToDesk、TeamViewer、向日葵、网易UU远程访问隐私防护测评