惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
I
InfoQ
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 【当耐特】
小众软件
小众软件
B
Blog RSS Feed
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
Engineering at Meta
Engineering at Meta
人人都是产品经理
人人都是产品经理
Microsoft Security Blog
Microsoft Security Blog
Last Week in AI
Last Week in AI
H
Help Net Security
爱范儿
爱范儿
云风的 BLOG
云风的 BLOG
博客园 - 司徒正美
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Microsoft Azure Blog
Microsoft Azure Blog
L
LangChain Blog
WordPress大学
WordPress大学
GbyAI
GbyAI
Google DeepMind News
Google DeepMind News
腾讯CDC

博客园 - 鄙人取个名字好难

Kafka Rebalance 机制 阿里云百炼实战-Spring AI 连接 AI应用API 阿里云百炼实战-IDEA集成Claude Code AI简介 Java进阶(八)动态代理 Hadoop(一)Linux环境搭建 Hadoop(二)基本概念 Hadoop(三)命令指南 Ubuntu中SVN服务端安装 Docker(六)安装telnet命令 MySQL实用查询语句 Java进阶(七)布隆过滤器 NIO面试题 TCP/IP面试题 SPRING面试题 SpringBoot(五)原理剖析:Transaction原理 SpringBoot(四)原理剖析:AOP原理 SpringBoot(三)原理剖析:IOC原理 SpringBoot(二)原理剖析:AutoConfiguration原理 SpringBoot(一)原理剖析:SpringApplication启动原理
多线程(七)AQS
鄙人取个名字好难 · 2026-09-14 · via 博客园 - 鄙人取个名字好难

  AQS(AbstractQueuedSynchronizer,抽象队列同步器) 是 Java 并发包(java.util.concurrent)的绝对核心ReentrantLockCountDownLatchSemaphoreReentrantReadWriteLock 等底层全部依赖 AQS

一、 核心思想:模板方法模式

  • AQS 负责:维护同步状态(state)、管理线程的排队与阻塞、唤醒。

  • 子类负责:定义什么是“获取锁成功”和“释放锁成功”(即如何操作 state)。

  AQS 定义了几个关键方法,子类可以选择性重写(以下方法在 AQS 中默认抛出 UnsupportedOperationException,强制子类按需实现):

tryAcquire(int) 独占模式获取锁(如 ReentrantLock
tryRelease(int) 独占模式释放锁
tryAcquireShared(int) 共享模式获取锁(如 SemaphoreCountDownLatch
tryReleaseShared(int) 共享模式释放锁
isHeldExclusively() 是否被当前线程独占
protected boolean isHeldExclusively() {
     throw new UnsupportedOperationException();
}

二、 核心结构

示例代码取自JDK21

1. volatile int state(同步状态)

    /**
     * The synchronization state.
     */
    private volatile int state;

  不同的工具赋予它不同的含义:

  • ReentrantLockstate = 0 表示无锁,state > 0 表示锁被重入次数。【独占模式

final boolean tryLock() {
            Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (compareAndSetState(0, 1)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            } else if (getExclusiveOwnerThread() == current) {
                if (++c < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(c);
                return true;
            }
            return false;
        }
  • Semaphorestate 表示可用许可数量。

  • CountDownLatchstate 表示剩余计数。【共享模式


/**
* Synchronization control For CountDownLatch.
* Uses AQS state to represent count.
*/
int getCount() {
            return getState();
        }

        protected int tryAcquireShared(int acquires) {
            return (getState() == 0) ? 1 : -1;
        }

2. FIFO 双向队列

  当线程获取锁失败时,会被包装成 Node 节点,加入队列尾部等待。

abstract static class Node {
        volatile Node prev;       // initially attached via casTail
        volatile Node next;       // visibly nonnull when signallable
        Thread waiter;            // visibly nonnull when enqueued
        volatile int status;      // written by owner, atomic bit ops by others

        // methods for atomic operations
        final boolean casPrev(Node c, Node v) {  // for cleanQueue
            return U.weakCompareAndSetReference(this, PREV, c, v);
        }
        final boolean casNext(Node c, Node v) {  // for cleanQueue
            return U.weakCompareAndSetReference(this, NEXT, c, v);
        }
        final int getAndUnsetStatus(int v) {     // for signalling
            return U.getAndBitwiseAndInt(this, STATUS, ~v);
        }
        final void setPrevRelaxed(Node p) {      // for off-queue assignment
            U.putReference(this, PREV, p);
        }
        final void setStatusRelaxed(int s) {     // for off-queue assignment
            U.putInt(this, STATUS, s);
        }
        final void clearStatus() {               // for reducing unneeded signals
            U.putIntOpaque(this, STATUS, 0);
        }

        private static final long STATUS
            = U.objectFieldOffset(Node.class, "status");
        private static final long NEXT
            = U.objectFieldOffset(Node.class, "next");
        private static final long PREV
            = U.objectFieldOffset(Node.class, "prev");
    }

View Code

  JDK 21 AQS Node 的核心变化