当前位置: 首页 > 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.dtcms.com/a/264463.html

相关文章:

  • 阿里巴巴Java开发手册(1.3.0)
  • transformers==4.42.0会有一个BUG
  • 第一修改器 1.0.2 | 免root,支持多开和游戏本地数据修改的强大工具
  • Rancher Server + Kubernets搭建云原生集群平台
  • 【Part 3 Unity VR眼镜端播放器开发与优化】第四节|高分辨率VR全景视频播放性能优化
  • 从模型部署到AI平台:云原生环境下的大模型平台化演进路径
  • C++异步编程里避免超时机制
  • 【深度学习机器学习】Epoch 在深度学习实战中的合理设置指南
  • Linux--线程池
  • git本地分支回退到某个commit,并推送远程,使远程分支也恢复到这个commit
  • 【全网唯一】自动化编辑器 Windows版纯本地离线文字识别插件
  • 6.原始值的响应式方案
  • UniApp 加载 Web 页面完整解决方案
  • UniApp(vue3+vite)如何原生引入TailwindCSS(4)
  • YOLOv11深度解析:Ultralytics新一代目标检测王者的创新与实践(附网络结构图+训练/推理/导出全流程代码详解)
  • 【Erdas实验教程】024:遥感图像辐射增强(亮度反转Brightness Inversion)
  • Python数据解析与图片下载工具:从JSON到本地文件的自动化流程
  • springboot使用redisTemplate的方法,详细说明
  • 以智能楼宇自动化控制系统为基石,构筑绿色建筑节能增效新标杆
  • cmake笔记
  • 【分明集合】特征函数、关系与运算
  • 【格与代数系统】格与哈斯图
  • 笨方法学python-习题12
  • Sql注入中万能密码order by联合查询利用
  • 应急响应类题练习——玄机第四章 windows实战-emlog
  • Foundation 5 安装使用教程
  • SQL SELECT 语句
  • 在线租房平台源码+springboot+vue3(前后端分离)
  • 应急响应类题练习——玄机第五章 Windows 实战-evtx 文件分析
  • 6.Docker部署ES+kibana