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

AQS机制详解与总结

AQS(AbstractQueuedSynchronizer)机制详解与总结

  • 一. AQS(AbstractQueuedSynchronizer)简介
    • 1. 核心理念:
    • 2. 核心成员变量state:
    • 3. 工作机制简述:
  • 二、AQS的核心任务
  • 三、AQS的核心组成
  • 四、CAS 与 AQS 的区别与联系
    • 1. CAS(Compare-And-Swap)
    • 2. AQS
    • 3. 关系总结
  • 五、使用 AQS 实现可重入公平锁 实现步骤

一. AQS(AbstractQueuedSynchronizer)简介

AQS 是 Java 并发包中用于构建锁(如 ReentrantLock)、同步器(如 SemaphoreCountDownLatch)和协作工具类的核心框架。

1. 核心理念:

  • 独占资源控制: 当共享资源空闲时,线程尝试通过原子操作获得资源,并设置为锁定状态。
  • 队列化等待机制: 如果资源被占用,线程将被加入一个基于 FIFO 的虚拟双向队列(CLH队列) 中进行阻塞等待,直到被唤醒再次尝试。

2. 核心成员变量state:

// 表示同步状态的变量
private volatile int state;
  • state 是 AQS 中用于表示同步状态的关键变量。
    • ReentrantLock 中,state 表示锁的重入次数;
    • Semaphore 中,state 表示剩余的许可证数量;
    • CountDownLatch 中,state 表示倒计时计数。
  • 该变量由 volatile 修饰,确保多线程间的可见性。
  • 所有对 state 的修改均通过 CAS(Compare-And-Swap)操作 保证原子性,避免使用重量级的锁。

3. 工作机制简述:

      ┌───────────────┐
      │     线程A     │
      └─────┬─────────┘
            │ acquire()
            ▼
   ┌─────────────────────┐
   │    AQS(框架)       │
   │  ┌───────────────┐  │
   │  │ state(volatile)│◄───CAS原子更新
   │  └───────────────┘  │
   │  ┌───────────────┐  │
   │  │ FIFO等待队列    │◄─入队/出队/唤醒线程
   │  └───────────────┘  │
   └─────────────────────┘

(1)获取锁(Acquire):

  • 使用 CAS 尝试修改 state
  • 成功:表示当前线程获取锁成功,继续执行。
  • 失败:进入等待队列(CLH),阻塞当前线程。

(2)释放锁(Release):

  • 同样使用 CAS 更新 state
  • 如果 state 变为允许状态,则唤醒等待队列中的下一个线程。

二、AQS的核心任务

在这里插入图片描述

AQS 作为 Java 并发框架中的核心同步器框架,主要负责以下三个方面:

  1. 同步状态(state)的原子操作
    • 通过 volatile 保证可见性,CAS 保证原子性。
  2. 线程的阻塞与唤醒
    • 利用内置 FIFO 等待队列(CLH队列)管理线程挂起与恢复。
  3. 等待队列的管理
    • 包括节点的入队、出队、取消、唤醒等机制。

三、AQS的核心组成

组件说明
state 变量表示同步状态,具体含义由子类定义:
🔸 Semaphore:剩余许可证数量
🔸 CountDownLatch:倒计时计数
🔸 ReentrantLock:锁状态(含重入次数)
FIFO 等待队列线程在竞争失败后会进入队列,按照顺序等待资源
协作工具类方法acquire()release()await()countDown() 等,
具体行为由子类重写 tryAcquire()tryRelease() 实现

四、CAS 与 AQS 的区别与联系

1. CAS(Compare-And-Swap)

  • 一种无锁原子操作机制。
  • 依赖于硬件指令实现原子性。
  • 三个操作数:V(内存值)、A(期望值)、B(更新值)
  • 如果 V == A,则将 V 更新为 B;否则什么都不做。

2. AQS

  • 一套**构建同步器(如锁、信号量)**的抽象框架。
  • 内部通过 volatile state 表示状态。
  • 使用 CAS 操作来更新 state,保证原子性。
  • 通过 CLH 队列管理线程等待。

3. 关系总结

  • AQS 依赖 CAS 实现对 state 的原子更新。
  • AQS 封装了大量与线程调度、状态管理、阻塞唤醒相关的逻辑,而 CAS 是实现原子性的关键技术手段

五、使用 AQS 实现可重入公平锁 实现步骤

1. 继承 AbstractQueuedSynchronizer

  • 创建一个静态内部类,继承 AQS。
  • 重写核心方法:
    • tryAcquire(int arg)
    • tryRelease(int arg)
    • isHeldExclusively()

2. 实现可重入逻辑

  • tryAcquire 中判断:
    • 若当前线程已持有锁,则支持重入(state++)。
    • 否则尝试通过 CAS 获取锁(state=0 -> 1)。

3. 实现公平性机制

  • tryAcquire 中优先检查等待队列:
    • 若有前驱节点在等待,当前线程需排队,不可直接竞争锁。

4. 封装为外部锁类

  • 外部类持有 AQS 子类的实例。
  • 提供 lock()unlock() 方法,内部调用 AQS 的同步逻辑。

http://www.dtcms.com/a/122893.html

相关文章:

  • java方法07:加减乘除计算器
  • rkmpp 解码 精简mpi_dec_test.c例程
  • LeetCode 热题 100 题解记录
  • Docker Hello World
  • 计算机网络 实验三:子网划分与组网
  • GaussDB性能调优:从根因分析到优化落地
  • 10. git switch
  • Java MCP SDK 开发笔记(一)
  • 深度学习疑问--Transformer【3】:transformer的encoder和decoder分别有什么用?encoder是可以单独使用的吗
  • WHAT - React 进一步学习推荐
  • Electron 应用太重?试试 PakePlus 轻装上阵
  • LVM 扩容详解
  • 0 std::process::Command 介绍
  • 中小型网络拓扑图静态路由方式
  • 监测fastapi服务并自动拉起(不依靠dockerfile)
  • 低代码开发平台:飞帆画 echarts 仪表盘
  • Redis最佳实践——用户会话管理详解
  • 金陵幻境录——六朝古都的科技诗篇-南京
  • go游戏后端开发29:实现游戏内聊天
  • 用 HTML 网页来管理 Markdown 标题序号
  • 【微服务架构】SpringCloud Alibaba(九):分布式事务Seata使用和源码分析(TCC模式、Saga模式)
  • 分布式锁阿
  • 软件功能性测试有多重要?功能性测试工具有哪些?
  • Cocos Creator新手学习
  • day25学习Pandas库
  • mysql的主从复制
  • 中文语义相似度 + 去除标签后的网页文本(爬虫数据)
  • 彩色路径 第32次CCF-CSP计算机软件能力认证
  • 服务器运维ACL访问控制列表如何配置
  • 【Leetcode-Hot100】字母异位词分组