Semaphore通过许可数硬性限制并发线程数,适用于单机资源保护;需static final全局复用,acquire/release配对且加超时,不支持分布式限流。

Semaphore 实现限流控制并发访问,核心是用“许可数”硬性约束同一时刻能进入临界区的线程数量,不看时间窗口、不计历史请求,只盯住“现在正在跑几个”。它轻量、零依赖、响应快,特别适合单机内保护下游资源(如 HTTP 连接池、DB 连接、文件句柄)或对接有明确并发上限的第三方系统。
初始化一个共享的 Semaphore 实例
限流对象必须全局唯一、复用,不能每次请求都 new 一个:
- 推荐声明为 static final,确保所有线程竞争同一许可池
- 构造参数即最大并发数,例如
new Semaphore(5)表示最多 5 个线程可同时执行受控逻辑 - 默认非公平模式(性能更好),除非业务强依赖请求顺序,否则不用传
true
在真正耗资源的位置前后配对 acquire() 和 release()
许可获取点要贴近实际开销操作,避免空转占坑:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 不要在 Controller 入口就 acquire,而应在调用远程接口、执行 SQL 或读写大文件前才申请
- 必须用 try-finally 包裹业务逻辑,release() 放在 finally 块中,防止异常导致许可泄漏
- 释放许可不要求是同一个线程,但必须保证每次 acquire() 后有且仅有一次 release()
生产环境务必加超时,避免线程池被拖垮
无超时的 acquire() 可能让 Tomcat 或 Netty 工作线程无限等待,最终耗尽连接池:
立即学习“Java免费学习笔记(深入)”;
- 改用
tryAcquire(1, 200, MILLISECONDS),超时建议设 100–300ms - 超时后直接返回 429 或抛业务异常,不进入后续逻辑
- 拒绝请求比卡住线程更安全,也利于上游快速失败重试
注意它的能力边界:单机有效,不跨 JVM
Semaphore 是 JVM 内部同步工具,天然不具备分布式能力:
- 部署 3 台服务,每台都配
new Semaphore(5),实际总并发就是 15 - 若需集群级限流,必须上层引入 Redis + Lua、Sentinel 或网关统一限流
- 它适合内部管理接口、低 QPS 定时任务、强依赖型老核心系统调用等轻量稳定场景

















