☰
JAVA面试-并发篇 05-并发包AQS队列实现原理是什么
2026/10/7 12:07:53 网站建设 项目流程

Java并发包AQS队列实现原理

一、文章概述

AQS(AbstractQueuedSynchronizer)是Java.util.concurrent包的核心基石,为ReentrantLock、CountDownLatch、Semaphore等几乎所有并发工具提供了统一的同步实现框架。其核心思想是:用一个volatile修饰的int型state变量表示同步状态,配合一个FIFO的**CLH(Craig, Landin, and Hagersten)**双向等待队列,实现线程的排队、阻塞与唤醒机制,解决了同步器实现的重复劳动问题。

二、核心数据结构

组件类型核心作用
statevolatile int0=无锁,>0=持有锁次数,天然支持可重入
等待队列CLH双向链表存储所有获取锁失败的阻塞线程
Node节点内部类封装线程引用、等待状态、前后指针
节点状态int常量SIGNAL(等待唤醒)、CANCELLED(已取消)等

三、获取锁核心执行流程

是

否

是

否

线程调用acquire

tryAcquire成功

执行同步代码

构造Node节点CAS入队

自旋检查前驱是否为头节点

再次tryAcquire成功

设为新头节点

park阻塞当前线程

被前驱节点unpark唤醒

四、节点状态流转

新建节点

前驱设为SIGNAL

被唤醒并获锁

线程中断/超时

队列自动清理

初始状态

INITIAL

SIGNAL

ACQUIRED

CANCELLED

结束

五、关键设计要点

  1. 无锁化修改:所有对state和队列指针的操作均通过Unsafe类的CAS实现,避免了重量级锁的开销
  2. 精确唤醒:使用LockSupport.park/unpark替代传统wait/notify,支持单个线程精确唤醒,避免虚假唤醒
  3. 可扩展架构:采用模板方法模式,子类仅需实现以下5个方法,即可自定义独占/共享同步逻辑:
    • tryAcquire(int):独占式获取同步状态
    • tryRelease(int):独占式释放同步状态
    • tryAcquireShared(int):共享式获取同步状态
    • tryReleaseShared(int):共享式释放同步状态
    • isHeldExclusively():判断当前线程是否独占同步状态

六、释放锁完整流程(时序图,不考虑可重入场景)

队列阻塞线程AQS框架持有锁线程队列阻塞线程AQS框架持有锁线程调用release() 发起锁释放执行tryRelease(),将state置为0遍历队列,定位头节点的后继有效节点LockSupport.unpark() 唤醒阻塞线程尝试获取同步状态获取锁成功,执行同步代码

总结

AQS通过"状态变量+CLH等待队列"的极简设计,抽象了并发同步的通用逻辑,将复杂的线程调度封装在框架内部,极大降低了自定义同步器的开发难度,是Java并发编程中最经典的设计之一。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询