semaphore是单机轻量级并发控制工具,靠许可证数限制同一时刻执行业务逻辑的线程数,不支持分布式协调,适用于数据库连接池限流、api调用节制等单机资源保护场景。

Semaphore 是一种轻量、可控的并发控制工具,核心作用是限制同一时刻能执行某段逻辑的线程数量,而不是保证互斥。它不解决分布式问题,也不感知响应延迟,但胜在无依赖、启动快、逻辑清晰——适合单机场景下的资源保护,比如数据库连接池限流、第三方 API 调用节制、定时任务并发压制等。
明确信号量的适用边界
它只是 JVM(或进程)内计数器,每个实例独立维护许可数。例如:部署 3 台服务,每台初始化 new Semaphore(5),实际总并发能力就是 15,不是 5。它无法跨节点协调,也不能替代 Redis + Lua 或 Sentinel 等集中式方案。如果你的系统已上云原生、多副本自动扩缩容,别指望靠它做全局统一限流。
正确初始化与安全使用
必须确保 Semaphore 实例全局唯一且生命周期与应用一致:
- Spring 环境下声明为
@Bean,避免每次 new 出新对象 - 禁止在异步线程(如
@Async、CompletableFuture)中acquire()后,在主线程release()—— 必须同一线程配对 - 所有
acquire()后,必须在finally块中调用release(),否则异常中断会导致许可永久泄漏 - 优先选用
tryAcquire(long timeout, TimeUnit unit),设 100~300ms 超时,避免线程池被阻塞耗尽
把限流点放在真正耗资源的位置
不要在 Controller 入口就加 tryAcquire()。接口里若含鉴权、日志、参数校验等轻量逻辑,应把这些放许可检查之前;只把真正消耗资源的操作(如调第三方 HTTP、写数据库、生成 PDF 文件)包进临界区。否则空转也占着许可,吞吐效率反而下降。
叠加失败统计实现简易熔断
Semaphore 本身不带熔断能力,但可配合状态机模拟:
- 用
AtomicInteger统计最近 60 秒内的失败请求数和总请求数 - 失败率超阈值(如 50%)且总请求数 ≥20,将开关置为 OPEN
- OPEN 状态下直接拒绝请求(跳过
tryAcquire()),持续 30 秒后进入 HALF-OPEN,只放行 1~2 个试探请求 - 试探成功则恢复服务,失败则重置计时器











