Last updated on 2025-11-23T21:13:40+08:00
1. TODO
2. 脑图
Xmind
Edraw
Hexo 地址
👉 http://blog.wangjia.ink/2025/11/19/源码:java.util.concurrent.Semaphore源码解析/
3. 基础部分
3.1. Semaphore 概述
Semaphore 是一个具体类
信号量(Semaphore)是使用 AQS 实现的共享模式的同步器。State 和共享资源分别表示以下含义:
State 表示剩余的 “许可证” 的数量
- 共享资源表示持有 “许可证” 期间被允许执行的操作
我们可以将 Semaphore 简单的理解为:可重复的、既能做减法也能做加法的计数器,计的数就是 “许可证”
[!NOTE] 注意事项
- 简单理解
CountDownLatch、CyclicBarrier、Semaphore:
CountDownLatch 是门闩开启才能继续执行
CyclicBarrier 是 “互相等待” 都准备好才能继续执行
Semaphore 是拿到 “许可证” 才能继续执行
3.2. Semaphore 应用场景
3.2.1. 并发控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class MyFlowControl { private static final Semaphore mySemaphore = new Semaphore(10); public void handleRequest() { try { mySemaphore.acquire(); ... } catch (InterruptedException e) { e.printStackTrace(); } finally { mySemaphore.release(); } } }
|
[!NOTE] 注意事项
- 无论是线程饥饿、流量控制,还是
IO 阻塞,这些问题的本质都是相同的:因无法获取所需要的资源,导致无法继续执行。针对这种 “资源匮乏” 的问题,通常有五种解决方案:
- 强制排队
- 资源预留
- 及时止损
- 异步处理
- 降级处理
- 启动告警
- 异步编程回调
- 随即避让
- 调整优先级
- 流量控制主要包括并发控制和速率限制
3.2.2. 资源池管理
常见的资源池包括连接池、线程池、对象池
以连接池为例,可以将连接池中的连接的数量与 Semaphore 的 ”许可证“ 的数量关联起来。在获取连接之前先获取 ”许可证“,在归还连接之后再归还 ”许可证“
4. 内部类
4.1. Sync
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| abstract static class Sync extends AbstractQueuedSynchronizer { Sync(int permits) { setState(permits); } final int getPermits() { return getState(); } final int nonfairTryAcquireShared(int acquires) { for (;;) { int available = getState(); int remaining = available - acquires; if (remaining < 0 || compareAndSetState(available, remaining)) return remaining; } } protected final boolean tryReleaseShared(int releases) { for (;;) { int current = getState(); int next = current + releases; if (next < current) throw new Error("Maximum permit count exceeded"); if (compareAndSetState(current, next)) return true; } } final void reducePermits(int reductions) { for (;;) { int current = getState(); int next = current - reductions; if (next > current) throw new Error("Permit count underflow"); if (compareAndSetState(current, next)) return; } }
final int drainPermits() { for (;;) { int current = getState(); if (current == 0 || compareAndSetState(current, 0)) return current; } } }
|
4.2. FairSync
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| static final class FairSync extends Sync { FairSync(int permits) { super(permits); } protected int tryAcquireShared(int acquires) { for (;;) { if (hasQueuedPredecessors()) return -1; int available = getState(); int remaining = available - acquires; if (remaining < 0 || compareAndSetState(available, remaining)) return remaining; } } }
|
4.3. NonfairSync
1 2 3 4 5 6 7 8 9 10 11
| static final class NonfairSync extends Sync { NonfairSync(int permits) { super(permits); } protected int tryAcquireShared(int acquires) { return nonfairTryAcquireShared(acquires); } }
|
5. 构造方法
5.1. Semaphore(int permits)
1 2 3 4 5
| public Semaphore(int permits) { sync = new NonfairSync(permits); }
|
5.2. Semaphore(int permits, boolean fair)
1 2 3 4 5
| public Semaphore(int permits, boolean fair) { sync = fair ? new FairSync(permits) : new NonfairSync(permits); }
|