semaphore共享锁基于aqs共享模式实现,核心是state原子操作与线程排队:acquire()触发tryacquireshared()尝试获取许可,返回≥0则成功并唤醒后继;release()调用tryreleaseshared()释放许可并传播唤醒。

Semaphore 的共享锁获取与释放过程,本质上是基于 AQS(AbstractQueuedSynchronizer)的 共享模式 实现的,核心在于对 AQS 内部状态变量 state 的原子操作和线程排队机制。剖析时需聚焦 Sync 子类、tryAcquireShared / tryReleaseShared 方法,以及公平性逻辑差异。
共享锁获取:acquire() → tryAcquireShared()
调用 acquire() 后,最终进入 AQS 的 acquireSharedInterruptibly(),再委托给子类实现的 tryAcquireShared(int acquires)。该方法决定是否能成功获取许可:
- 返回值 ≥ 0 表示获取成功,AQS 会继续唤醒后续共享节点;
- 返回值
关键逻辑在 Sync 的两个子类中:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
非公平模式(NonfairSync):直接尝试 CAS 修改
state(即许可数),不检查队列是否有等待者。只要剩余许可足够,就立即更新成功; -
公平模式(FairSync):先调用
hasQueuedPredecessors()判断队列头部是否有其他等待线程,若有则直接返回 -1(失败),避免插队;只有队列为空或当前线程是队首时,才执行 CAS。
共享锁释放:release() → tryReleaseShared()
release() 调用 AQS 的 releaseShared(),进而触发子类重写的 tryReleaseShared(int releases)。该方法负责安全地增加许可数:
- 使用无限循环 + CAS 原子更新
state,防止并发 release 导致计数错误; - 成功后返回
true,AQS 会唤醒队列中等待的共享节点(即阻塞的 acquire 线程); - 注意:release 不校验调用线程是否曾 acquire 过,也不限制释放数量——可超额释放(如 state=2 时 release(5),state 变为 7),这与 ReentrantLock 严格配对不同。
state 的语义与边界处理
state 在 Semaphore 中纯粹表示“可用许可数”,初始值由构造参数 permits 设定:
- acquire 时:执行
state = state - acquires,若结果 - release 时:执行
state = state + releases,无上限(除非溢出,但实践中极少发生); - 不区分线程身份——同一线程多次 acquire 会持续减少 state,多次 release 会持续增加,不具备重入性。
阻塞与唤醒的协作机制
当 acquire 失败时,线程被封装为 Node 加入 AQS 同步队列,以共享模式(Node.SHARED)入队;release 成功后,AQS 遍历队列,从头开始唤醒所有标记为 SHARED 的连续节点(即支持“传播唤醒”),确保多个等待线程能依次获取许可。这种设计天然适配“一批资源供多线程争用”的场景,比如限流、连接池控制。










