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

【2025面试常问Java八股】AQS介绍(AbstractQueuedSynchronizer 抽象队列同步器)

经典回答

"AbstractQueuedSynchronizer(AQS)是Java并发包的核心框架,为构建锁和同步器提供了底层支持。像ReentrantLock、Semaphore这些常用并发工具都是基于AQS实现的。它的核心思想是通过一个int类型的state变量表示同步状态,配合CLH队列管理线程的排队与唤醒。"

"AQS使用volatile修饰的state变量表示同步状态,通过CAS操作保证原子性修改。比如ReentrantLock用它记录重入次数,Semaphore用它表示剩余许可数。"

"采用CLH变体的FIFO双向队列管理等待线程。每个线程被封装成Node节点,通过waitStatus标识线程状态(如CANCELLED、SIGNAL)。"

AQS中的阻塞队列是一个CLH队列。CLH(Craig, Landin, and Hagersten)队列是一种用于实现自旋锁的有效数据结构。它是由Craig, Landin和Hagersten首次提出的,因此得名。

"AQS采用模板方法模式,定义了acquire/release等骨架方法,而将tryAcquire/tryRelease等具体操作交给子类实现,这种设计非常优雅。"

"可以把AQS想象成游乐园的排队系统:游客(线程)先尝试直接进入(tryAcquire)如果满员(获取失败),就去排队区(CLH队列)取号等待当前游客离开(release)时,系统通知下一位游客(unpark)共享模式就像团体票,可以一次性放行多人"

高性能:通过自旋+CAS减少阻塞

灵活性:支持独占/共享两种模式

可扩展:基于模板方法方便实现各种同步器

公平可选:支持公平与非公平策略

"在JUC包中有很多经典实现:

ReentrantLock:可重入独占锁

CountDownLatch:倒计时门闩

Semaphore:信号量控制

ThreadPoolExecutor.Worker:线程池工作线程控制

比如ReentrantLock的公平锁实现,就是在tryAcquire中先检查hasQueuedPredecessors()确保先来先服务。"

"理解AQS的设计,不仅能帮助我们更好地使用JUC工具,当需要实现特定需求的同步器时,也能基于AQS快速开发。"

AQS源码

public abstract class AbstractQueuedSynchronizer

extends AbstractOwnableSynchronizer

implements java.io.Serializable {

}

Java AQS (AbstractQueuedSynchronizer) 深度解析

AQS 是 Java 并发包的核心基础框架,为构建锁和同步器提供了底层支持。理解 AQS 是掌握 Java 并发编程的关键。

一、AQS 核心概念

1. 基本定位

  • 全称:AbstractQueuedSynchronizer

  • 位置java.util.concurrent.locks 包

  • 作用:构建锁和同步器的框架(如 ReentrantLock、CountDownLatch 等)

2. 核心思想

  • CLH 队列:基于 FIFO 等待队列的变种

  • 状态管理:通过单个原子 int 值表示同步状态

  • 模板模式:需要子类实现特定方法

二、核心数据结构

1. 同步状态

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

2. 等待队列节点

static final class Node {volatile int waitStatus;    // 等待状态volatile Node prev;         // 前驱节点volatile Node next;         // 后继节点volatile Thread thread;     // 关联线程Node nextWaiter;            // 条件队列链接
}

3. 等待状态值

常量名含义
1CANCELLED线程已取消
-1SIGNAL后继线程需要唤醒
-2CONDITION在条件队列中等待
-3PROPAGATE共享模式下传播唤醒

三、工作原理解析

1. 独占模式(如 ReentrantLock)

2. 共享模式(如 Semaphore)

四、关键方法解析

1. 需要子类实现的方法

方法说明
tryAcquire(int)尝试获取独占锁
tryRelease(int)尝试释放独占锁
tryAcquireShared(int)尝试获取共享锁
tryReleaseShared(int)尝试释放共享锁
isHeldExclusively()是否被当前线程独占

2. 重要模板方法

方法说明
acquire(int)独占式获取锁
acquireInterruptibly(int)可中断获取
tryAcquireNanos(int, long)带超时获取
release(int)独占式释放
acquireShared(int)共享式获取
releaseShared(int)共享式释放

五、AQS 在 JUC 中的应用

1. ReentrantLock

final Sync extends AbstractQueuedSynchronizer {// 实现tryAcquire/tryReleaseprotected final boolean tryAcquire(int acquires) {Thread current = Thread.currentThread();int c = getState();if (c == 0) {if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}else if (current == getExclusiveOwnerThread()) {setState(c + acquires); // 可重入return true;}return false;}
}

2. CountDownLatch

private static final class Sync extends AbstractQueuedSynchronizer {Sync(int count) { setState(count); }protected int tryAcquireShared(int acquires) {return (getState() == 0) ? 1 : -1;}protected boolean tryReleaseShared(int releases) {// 自旋减少状态值for (;;) {int c = getState();if (c == 0) return false;int nextc = c-1;if (compareAndSetState(c, nextc))return nextc == 0;}}
}

六、AQS 设计精髓

1. 性能优化点

  • CAS 操作:状态变更使用 compareAndSetState

  • 自旋检查:入队前多次尝试获取锁

  • 头节点检查:只有前驱是头节点才尝试获取

2. 公平性实现

// 公平锁实现示例
protected final boolean tryAcquire(int acquires) {if (!hasQueuedPredecessors() && // 检查是否有排队线程compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}// ...
}

3. 条件变量支持

public class ConditionObject implements Condition {private transient Node firstWaiter; // 条件队列头private transient Node lastWaiter;  // 条件队列尾public final void await() throws InterruptedException {Node node = addConditionWaiter();int savedState = fullyRelease(node);// ...}
}

七、AQS 使用示例

自定义互斥锁

class Mutex implements Lock {private final Sync sync = new Sync();static class Sync extends AbstractQueuedSynchronizer {protected boolean tryAcquire(int ignore) {return compareAndSetState(0, 1);}protected boolean tryRelease(int ignore) {setState(0);return true;}}public void lock() { sync.acquire(1); }public void unlock() { sync.release(1); }// 其他方法实现...
}

AQS 通过精妙的设计,将同步器的通用逻辑抽象出来,让开发者只需关注特定同步策略的实现。理解 AQS 的工作机制,不仅能帮助更好地使用 JUC 中的工具类,也能为设计自定义同步组件提供坚实基础。


http://www.mrgr.cn/news/99185.html

相关文章:

  • Winform发展历程
  • 【前端】跟着maxkb学习logicflow流程图画法
  • UWP特性分析
  • 第七节:React HooksReact 18+新特性-并发模式(Concurrent Mode)解决了什么问题?
  • Golang 的 GMP 协程模型详解
  • 32-工艺品商城小程序
  • 33-公交车司机管理系统
  • 嵌入式硬件常用总线接口知识体系总结和对比
  • (二)mac中Grafana监控Linux上的MySQL(Mysqld_exporter)
  • 线性代数 | 知识点整理 Ref 1
  • Redis 事件循环(Event Loop)
  • RV1126网络环境TFTPNFS搭建(四)
  • 系统与网络安全------弹性交换网络(1)
  • 大数据应用开发——大数据平台集群部署(三)
  • 用Python玩转倒排索引:从原理到实战的趣味之旅
  • Semaphore的核心机制
  • Webview+Python:用HTML打造跨平台桌面应用的创新方案
  • 云梦数据平台
  • 小红书爬虫,小红书api,小红书数据挖掘
  • 滑动时间窗口实现重试限流