Semaphore 源码解析
Semaphore 源码解析:AQS 共享模式、许可传播机制与公平策略实现 🚀 道格·李为什么需要一个信号量 信号量(Semaphore)是操作系统教科书里最古老的并发原语之一,由 Edsger Dijkstra 在 1960 年代提出。但在 Java 1.0 ~ 1.4 时代,JDK 里并没有信号量——开发者只能用 synchronized 加一个计数器模拟,代码又长又容易出错。 道格·李在设计 JSR 166 时,需要将信号量引入 Java,原因很简单:synchronized 是互斥的(同一时刻只能一个线程进入),而很多并发控制场景需要的是"限制并发数量"而不是"限制到只有 1 个"。比如数据库连接池最多 10 个并发连接、文件读取最多 3 个线程同时打开、API 限流每秒 100 个请求——这些场景用 synchronized 无法表达。 Semaphore 的思路是许可计数:构造时定义 N 个"许可证",线程调用 acquire() 拿走一个许可(不够就阻塞),用完调用 release() 归还。许可与线程没有绑定关系——线程 A 获取的许可可以由线程 B 释放。这个设计很关键:它让 Semaphore 不仅可以用作"限流器",还可以用作"对象池管理器"或"同步器"。 在 AQS 框架中,Semaphore 使用的是共享模式(Shared Mode)——多个线程可以同时获取许可,不像 ReentrantLock 的独占模式那样一次只唤醒一个线程。 🏗️ 核心数据结构 🏗️ 整体类层次结构 Semaphore 和 ReentrantLock 的内部结构高度相似——都是通过内部类 Sync 间接继承 AQS,并通过两个子类实现公平/非公平策略。但有一个关键区别:Semaphore 使用的是 AQS 的 共享模式(Shared Mode),而非独占模式。 ...