源码:java.util.concurrent.Semaphore 源码解析

1. TODO


2. 脑图

  1. Xmind

  2. Edraw

  3. Hexo 地址
    👉 http://blog.wangjia.ink/2025/11/19/源码:java.util.concurrent.Semaphore源码解析/


3. 基础部分

3.1. Semaphore 概述

Semaphore 是一个具体类

信号量(Semaphore)是使用 AQS 实现的共享模式的同步器。State 和共享资源分别表示以下含义:

  1. State 表示剩余的 “许可证” 的数量
  2. 共享资源表示持有 “许可证” 期间被允许执行的操作

我们可以将 Semaphore 简单的理解为:可重复的、既能做减法也能做加法的计数器,计的数就是 “许可证”

[!NOTE] 注意事项

  1. 简单理解 CountDownLatchCyclicBarrierSemaphore
    1. CountDownLatch 是门闩开启才能继续执行
    2. CyclicBarrier 是 “互相等待” 都准备好才能继续执行
    3. 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] 注意事项

  1. 无论是线程饥饿、流量控制,还是 IO 阻塞,这些问题的本质都是相同的:因无法获取所需要的资源,导致无法继续执行。针对这种 “资源匮乏” 的问题,通常有五种解决方案:
    1. 强制排队
    2. 资源预留
    3. 及时止损
      1. 异步处理
      2. 降级处理
      3. 启动告警
      4. 异步编程回调
    4. 随即避让
    5. 调整优先级
  2. 流量控制主要包括并发控制和速率限制

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) // overflow
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) // underflow
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);

}


源码:java.util.concurrent.Semaphore 源码解析
https://wangjia5289.github.io/2025/11/19/源码:java.util.concurrent.Semaphore源码解析/
Author
咸阳猴🐒
Posted on
November 19, 2025
Licensed under