0

0

什么是Java中的信号量(Semaphore)_控制资源并发访问限流的实现

P粉602998670

P粉602998670

发布时间:2026-02-27 14:44:03

|

722人浏览过

|

来源于php中文网

原创

semaphore是许可证计数器,用于限流而非锁或通信;设总数后acquire()扣证、release()还证,典型场景如连接池限流;需成对调用且release()必放finally,避免泄漏;非公平模式默认高吞吐,公平模式可预测但性能低;仅单jvm有效,不可作分布式锁。

什么是java中的信号量(semaphore)_控制资源并发访问限流的实现

Java里Semaphore到底用来干啥

它不是锁,也不是线程通信工具,而是「许可证计数器」——你设好总数(比如5张票),每次acquire()就扣一张,release()就还一张。谁拿不到许可证,就阻塞或失败,不进临界区。

典型场景:限制数据库连接池最大活跃连接数、控制API调用频次、避免大量线程同时写磁盘。

常见错误现象:acquire()后忘了release(),导致许可证永远被占着;或者在异常路径里漏掉release(),资源彻底卡死。

  • 构造时传new Semaphore(3)表示最多3个并发,传true第二个参数启用公平模式(按等待顺序分配,性能略低但可预测)
  • 别用Semaphore替代synchronized——它不保证临界区内代码的原子性,只管“能不能进”
  • 如果想非阻塞获取,用tryAcquire(),返回boolean;想带超时,用tryAcquire(long, TimeUnit)

acquire()release()必须成对出现在同一作用域

很多人把acquire()放在try前,release()扔进finally,看着没问题,但一旦acquire()本身被中断(比如线程被interrupt()),就会抛InterruptedException,跳过finally,许可证没释放。

立即学习Java免费学习笔记(深入)”;

正确做法是:先确保拿到许可证,再进业务逻辑;释放操作必须包裹在try-finally里,且acquire()调用要处理中断。

ColorMagic
ColorMagic

AI调色板生成工具

下载
semaphore.acquire(); // 可能抛 InterruptedException
try {
    // 业务逻辑
} finally {
    semaphore.release(); // 这里必须执行
}
  • 如果业务逻辑可能抛异常,不影响release()执行,因为已在finally
  • 不要在catch里调用release()——那是重复释放,会多加许可证,破坏限流逻辑
  • 若用tryAcquire()非阻塞方式,成功才进try-finally,失败直接走其他路径

公平模式 vs 非公平模式的实际影响

默认是非公平的:new Semaphore(5),新线程可能插队抢到许可证,老线程一直等。公平模式new Semaphore(5, true)会让等待最久的线程优先获得。

性能差异明显:非公平吞吐高,公平模式上下文切换多、延迟略高,尤其在高竞争下更明显。

  • 限流类场景(如API网关)通常用非公平——响应快比排队准更重要
  • 调试或压测时开启公平模式,更容易复现资源争用问题
  • 注意:公平性只影响等待队列里的线程,不保证acquire()调用顺序和执行顺序一致

别把Semaphore当分布式锁用

Semaphore只在单JVM内有效。同一应用多个实例、微服务部署、容器重启后状态全丢——它不持久、不跨进程、不跨网络。

常见踩坑:用Semaphore做“全局请求限流”,结果每个Pod都自己算自己的5个并发,实际总并发变成5×Pod数。

  • 真要跨实例限流,得上Redis + Lua(如redisson.getSemaphore())或专门的限流服务(Sentinel、Resilience4j)
  • 本地限流+兜底可以保留Semaphore,但必须明确它是“最后一道本地防线”,不是唯一控制点
  • 监控时注意区分:JVM内许可证剩余数(可用availablePermits()查)和真实业务并发量可能不等——比如一个请求拿了证但卡在下游,许可证已占但没干活

真正难的从来不是调用acquire(),而是想清楚“这个许可证代表什么资源”“谁该还”“还错一次会发生什么”。限流逻辑一旦混进业务异常流,比没限更危险。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
什么是分布式
什么是分布式

分布式是一种计算和数据处理的方式,将计算任务或数据分散到多个计算机或节点中进行处理。本专题为大家提供分布式相关的文章、下载、课程内容,供大家免费下载体验。

401

2023.08.11

分布式和微服务的区别
分布式和微服务的区别

分布式和微服务的区别在定义和概念、设计思想、粒度和复杂性、服务边界和自治性、技术栈和部署方式等。本专题为大家提供分布式和微服务相关的文章、下载、课程内容,供大家免费下载体验。

248

2023.10.07

java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

365

2023.11.13

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

40

2025.11.30

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

721

2023.08.10

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

999

2023.11.02

内存数据库有哪些
内存数据库有哪些

内存数据库有Redis、Memcached、Apache Ignite、VoltDB、TimesTen、H2 Database、Aerospike、Oracle TimesTen In-Memory Database、SAP HANA和ache Cassandra。更多关于内存数据库相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

664

2023.11.14

mongodb和redis哪个读取速度快
mongodb和redis哪个读取速度快

redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

499

2024.04.02

Golang 并发编程模型与工程实践:从语言特性到系统性能
Golang 并发编程模型与工程实践:从语言特性到系统性能

本专题系统讲解 Golang 并发编程模型,从语言级特性出发,深入理解 goroutine、channel 与调度机制。结合工程实践,分析并发设计模式、性能瓶颈与资源控制策略,帮助将并发能力有效转化为稳定、可扩展的系统性能优势。

2

2026.02.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.9万人学习

C# 教程
C# 教程

共94课时 | 10.3万人学习

Java 教程
Java 教程

共578课时 | 73.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号