Semaphore是Java并发包中用于控制并发访问数量的计数信号量,通过acquire()和release()管理许可,适合资源池限流;初始化指定最大许可数,如new Semaphore(10)限制最多10个线程同时访问。

Semaphore 是 Java 并发包中用于控制并发访问数量的工具类,特别适合做资源池限流,比如数据库连接数限制。它不关心谁在用资源,只管“还有几个名额可用”,非常适合轻量、无状态的许可控制场景。
理解 Semaphore 的核心逻辑
Semaphore 本质是一个计数信号量,通过 acquire() 获取许可(计数减一),release() 归还许可(计数加一)。初始化时指定最大许可数,即允许同时访问资源的线程上限。
例如:构造 new Semaphore(10) 表示最多 10 个线程能同时拿到连接;第 11 个线程调用 acquire 会被阻塞,直到有线程 release。
用 Semaphore 管理数据库连接池(简易版)
实际项目中推荐用 HikariCP、Druid 等成熟连接池,但若需手动控制或做教学演示,Semaphore 可作为外层限流阀:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 定义一个全局 Semaphore 实例,许可数 = 最大连接数(如 20)
- 每次获取连接前先 acquire(),成功才从真实连接池(或 DriverManager)取连接
- 使用完连接后,在 finally 块中 release(),确保许可及时归还
- 建议搭配 try-with-resources 或显式 close,并在 close 后 release,避免连接泄漏导致许可永久丢失
注意公平性与超时处理
默认 Semaphore 是非公平的(可能造成饥饿),高一致性要求场景可启用公平模式:new Semaphore(10, true)
为防死锁或长时间等待,推荐用带超时的 acquire:
if (semaphore.tryAcquire(3, TimeUnit.SECONDS)) { ... } else { throw new RuntimeException("获取连接超时"); }- 超时后必须妥善处理降级逻辑(如返回错误、走缓存、拒绝请求)
和连接池配合使用的典型结构
不要用 Semaphore 替代连接池内部管理,而是把它放在连接获取入口处,作为“总闸门”:
- 连接池自身仍负责创建、复用、销毁物理连接
- Semaphore 控制“有多少线程正在尝试占用连接”,防止突发流量打爆连接池或数据库
- 二者职责分离:连接池管连接生命周期,Semaphore 管并发访问强度
不复杂但容易忽略。

















