当前位置: 首页
业界动态
Semaphore 限流器源码解析 AQS 共享模式实现原理详解

Semaphore 限流器源码解析 AQS 共享模式实现原理详解

热心网友 时间:2026-05-14
转载

各位Java开发者,在上一篇深入解析AQS独占模式与ReentrantLock之后,我们已经掌握了处理“互斥访问”的核心技术。然而,在实际的高并发系统设计与性能优化中,仅仅实现互斥是远远不够的。我们经常需要更精细的并发控制能力——精确管理同一时刻能够访问特定资源的线程数量。无论是实现API限流、数据库连接池管理、还是控制并行任务执行数量,这些场景都需要一种更强大的并发控制机制。

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

这一切功能背后的技术基石,正是AQS的共享模式。它是Semaphore(信号量)、CountDownLatch(倒计时器)、CyclicBarrier(循环屏障)等Java并发工具类的通用底层架构。理解AQS共享模式的工作原理,是掌握Java高并发编程的关键一步。

一、核心区别:AQS独占模式与共享模式对比

要快速理解两者的本质差异,只需记住这一句话:

  • 独占模式(Exclusive Mode):资源具有排他性,同一时刻仅允许一个线程持有。典型实现是ReentrantLock可重入锁。
  • 共享模式(Shared Mode):资源具有可共享性,允许多个线程同时持有。Semaphore信号量、CountDownLatch等工具都基于此模式构建。

二、AQS共享模式核心架构(基于JDK8源码)

首先查看AQS中支持共享模式的关键字段定义:

public abstract class AbstractQueuedSynchronizer {
    // 共享状态:多个线程可以同时访问和修改
    private volatile int state;
    // CLH同步队列头尾指针
    private transient volatile Node head;
    private transient volatile Node tail;
}

共享模式的设计思想非常直观易懂:

  • state字段在此模式下代表“可用资源的总数量”。
  • 线程申请资源时,通过CAS操作将state值减1;释放资源时,将state值加1。
  • 只要state > 0,就表示还有可用资源,允许多个线程并发获取。

三、AQS共享模式核心源码深度解析

1. 核心入口方法:acquireShared(int arg)

public final void acquireShared(int arg) {
    if (tryAcquireShared(arg) < 0) {
        // 获取资源失败 → 进入同步队列等待
        doAcquireShared(arg);
    }
}

这个方法有几个关键设计要点:

  • tryAcquireShared是模板方法,由具体的子类(如Semaphore、CountDownLatch)实现其具体逻辑。
  • 返回值语义:返回值≥0表示获取资源成功;返回值<0则表示获取失败,当前线程需要进入同步队列等待。

2. 核心逻辑:doAcquireShared入队与阻塞机制

private void doAcquireShared(int arg) {
    final Node node = addWaiter(Node.SHARED);
    boolean failed = true;
    try {
        boolean interrupted = false;
        for (;;) {
            final Node p = node.predecessor();
            if (p == head) {
                // 再次尝试获取共享资源
                int r = tryAcquireShared(arg);
                if (r >= 0) {
                    // 获取成功 → 传播唤醒后续的共享节点
                    setHeadAndPropagate(node, r);
                    p.next = null;
                    if (interrupted)
                        selfInterrupt();
                    failed = false;
                    return;
                }
            }
            // 检查并执行线程阻塞
            if (shouldParkAfterFailedAcquire(p, node) &&
                parkAndCheckInterrupt())
                interrupted = true;
        }
    } finally {
        if (failed)
            cancelAcquire(node);
    }
}

共享模式最显著的特征就体现在这里:唤醒传播机制(propagation)。当一个共享节点被唤醒并成功获取资源后,它会通过setHeadAndPropagate方法,主动尝试唤醒同步队列中后续的所有共享节点。这种设计实现了“连锁唤醒”效果,让多个等待线程能够高效地批量恢复执行,极大提升了并发性能。

3. 资源释放:releaseShared方法

public final boolean releaseShared(int arg) {
    if (tryReleaseShared(arg)) {
        // 释放成功 → 唤醒队列中的等待节点
        doReleaseShared();
        return true;
    }
    return false;
}

这里的doReleaseShared方法是AQS共享模式唤醒机制的核心。它通过循环检查和传播唤醒的算法,确保所有在同步队列中等待的共享线程都能被正确、高效地唤醒,避免了“唤醒丢失”问题。

四、Semaphore源码深度剖析(限流核心工具)

Semaphore是AQS共享模式最经典的应用实现,它的核心功能是控制最多N个线程同时访问特定资源。

1. Semaphore内部结构(JDK8实现)

public class Semaphore {
    private final Sync sync;

    abstract static class Sync extends AbstractQueuedSynchronizer {
        Sync(int permits) {
            setState(permits); // permits = 初始许可证数量
        }
    }

    // 非公平同步器(默认实现)
    static final class NonfairSync extends Sync {
        protected int tryAcquireShared(int acquires) {
            return nonfairTryAcquireShared(acquires);
        }
    }

    // 公平同步器
    static final class FairSync extends Sync {
        protected int tryAcquireShared(int acquires) {
            // 先检查同步队列,再尝试获取
        }
    }
}

2. 核心逻辑:非公平模式获取许可证

final int nonfairTryAcquireShared(int acquires) {
    for (;;) {
        int a vailable = getState();
        int remaining = a vailable - acquires;
        if (remaining < 0 ||
            compareAndSetState(a vailable, remaining))
            return remaining;
    }
}

这段代码的逻辑清晰明了:

  1. 获取当前可用许可证数量(从state字段读取)。
  2. 计算获取指定数量后的剩余许可证(remaining = state - acquires)。
  3. 如果remaining ≥ 0且CAS设置状态成功,则获取成功。
  4. 如果remaining < 0,则获取失败,线程将进入AQS同步队列等待。

3. 许可证释放实现

protected final boolean tryReleaseShared(int releases) {
    for (;;) {
        int current = getState();
        int next = current + releases;
        if (compareAndSetState(current, next))
            return true;
    }
}

释放操作本质上是增加state值(可用许可证数量),然后通过AQS的doReleaseShared方法唤醒同步队列中等待的线程,让它们有机会获取新释放的资源。

五、公平信号量与非公平信号量对比

这是使用Semaphore时需要理解的重要选择:

  • 非公平模式(默认):线程获取许可证时,会先直接尝试CAS抢占,抢不到再进入队列等待。这种方式减少了线程切换开销,吞吐量更高。
  • 公平模式:线程获取许可证前,会先检查AQS同步队列中是否有其他线程在等待。如果有,则自己必须入队等待,严格遵循先来后到的顺序,避免了线程“饥饿”问题。

对于大多数业务场景,使用默认的非公平模式即可获得最佳性能。只有在需要严格保证公平性的特殊场景下,才需要考虑使用公平模式。

六、Semaphore实战应用场景(可直接落地)

理解了Semaphore的实现原理,我们来看看它在实际系统中的典型应用:

  • API接口限流:限制某个关键接口同时处理的请求数不超过预设阈值(如20个)。
  • 数据库连接池控制:管理访问数据库连接等稀缺资源的并发数量。
  • 多线程任务流速控制:防止瞬间提交大量任务导致线程池过载,实现平滑的任务处理。
  • 系统资源访问控制:控制同时访问文件、网络连接等系统资源的线程数量。

标准的使用模板如下,务必注意在finally块中释放许可证,避免资源泄漏:

Semaphore semaphore = new Semaphore(20);
try {
    semaphore.acquire();  // 获取许可证
    // 执行受保护的业务逻辑
} finally {
    semaphore.release();  // 必须释放许可证
}

七、Java并发体系完整串联

至此,我们可以将JUC并发工具包的核心脉络完整串联起来:

  • ReentrantLock → 基于AQS独占模式,解决资源互斥访问问题。
  • Semaphore → 基于AQS共享模式,解决资源数量控制与限流问题。
  • CountDownLatch → 同样是AQS共享模式的应用(state减到0时唤醒所有等待线程)。
  • CyclicBarrier → 基于ReentrantLock和Condition实现,解决线程同步等待问题。
  • ThreadPoolExecutor → 其内部的工作线程控制、状态管理也大量运用了AQS的设计思想。

掌握了AQS的独占与共享这两种核心模式,意味着你已经打通了Java并发编程最底层的技术逻辑。这不仅能够帮助你深入理解JUC中各种并发工具的实现原理,更能让你在实际开发中设计出更高效、更稳定的并发控制系统。

来源:https://www.51cto.com/article/843074.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
卷积神经网络与普通神经网络的核心区别详解

卷积神经网络与普通神经网络的核心区别详解

探讨深度学习技术,卷积神经网络(CNN)与全连接神经网络(DNN,或称多层感知机MLP)是两种最基础且至关重要的模型架构。尽管同属神经网络家族,但它们在设计原理、计算机制及适用场景上存在本质区别。本文将深入解析CNN与普通神经网络的核心差异,帮助您根据具体任务选择最合适的模型。 一、网络结构:从“全

时间:2026-05-14 21:11
自然语言处理文本生成技术实现流畅风格化写作

自然语言处理文本生成技术实现流畅风格化写作

如何让机器生成的文字不仅读起来像人类所写,还能精准地模仿特定风格?这背后是自然语言处理(NLP)领域一系列核心技术与策略的深度整合。本文将系统拆解实现自然、流畅且风格化文本生成的关键路径与核心方法。 一、语言模型:文本生成的基石 构建高质量文本生成系统的第一步,是选择一个强大的“大脑”——即语言模型

时间:2026-05-14 21:11
淘宝数据采集工具推荐与使用指南

淘宝数据采集工具推荐与使用指南

在电商运营与数据分析工作中,高效、精准地获取淘宝平台数据,是众多商家、运营人员及市场研究者的普遍需求。面对海量订单、商品详情和店铺运营信息,传统人工采集方式不仅耗时费力,且容易产生误差。此时,机器人流程自动化(RPA)技术便成为一把高效的“数字化工具”,能够自动执行重复性高、规则明确的任务,让淘宝数

时间:2026-05-14 21:10
大语言模型十大应用场景与实战指南

大语言模型十大应用场景与实战指南

在信息爆炸的时代,人工智能技术正以前所未有的速度重塑着我们的世界。其中,大语言模型(Large Language Model, LLM)作为AI领域的一颗璀璨明星,其影响力已逐步渗透至社会经济的方方面面。今天,我们就来深入探讨一下LLM在十大关键领域中的实际应用,看看这项技术奇迹是如何解锁无限可能的

时间:2026-05-14 21:10
数字化信创概念起源与发展历程详解

数字化信创概念起源与发展历程详解

“数字化信创”这一概念的兴起,与“信创”产业的演进紧密相连。所谓“信创”,即信息技术应用创新,它并非孤立存在,而是在国家全面推进数字化转型的战略背景下,基于对信息安全与核心技术自主可控的日益重视,逐步发展并明确的重要产业方向。 一、信创概念的提出背景 全球数字化浪潮席卷而来,信息技术已成为驱动经济发

时间:2026-05-14 21:10
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜
热门教程
更多
  • 游戏攻略
  • 安卓教程
  • 苹果教程
  • 电脑教程