信号量(Semaphore)用于控制并发访问资源的线程数量,通过 acquire() 获取许可、release() 释放许可,确保最多指定数量的线程可同时执行,适用于限流与资源池管理。

在Java中,线程间的信号量控制主要通过 Semaphore 类来实现。Semaphore 是 java.util.concurrent 包中的一个同步工具,用于控制同时访问某一资源的线程数量,常用于限流、资源池管理等场景。
什么是信号量(Semaphore)
Semaphore 维护了一组许可证(permits)。当线程想要访问共享资源时,需要先获取许可。如果许可证可用,线程继续执行;如果没有可用许可,线程将被阻塞,直到有其他线程释放许可为止。
基本使用方法
以下是使用 Semaphore 控制线程并发的基本步骤:
- 创建 Semaphore 实例,指定许可证数量
- 在关键代码前调用 acquire() 方法获取许可
- 执行受控操作
- 完成后调用 release() 方法释放许可
示例代码:
立即学习“Java免费学习笔记(深入)”;
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
private Static final Semaphore semaphore = new Semaphore(2); // 允许最多2个线程同时执行
public static void main(String[] args) {
for (int i = 0; i new Thread(() -> {
try {
semaphore.acquire(); // 获取许可
System.out.println(Thread.currentThread().getName() + ” 获取到许可,开始执行”);
Thread.sleep(2000); // 模拟工作
System.out.println(Thread.currentThread().getName() + ” 执行完成,释放许可”);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
semaphore.release(); // 释放许可
}
}).start();
}
}
}
常用方法说明
Semaphore 提供了多个灵活的方法来满足不同需求:
- acquire():获取一个许可,可能阻塞
- acquire(int permits):获取多个许可
- tryAcquire():尝试获取许可,立即返回布尔值,不阻塞
- tryAcquire(long timeout, TimeUnit unit):在指定时间内尝试获取许可
- release():释放一个许可
- availablePermits():返回当前可用许可数
公平性设置
Semaphore 构造函数支持设置是否为公平模式:
new Semaphore(2, true); // 公平模式,按等待顺序分配许可
new Semaphore(2, false); // 非公平模式(默认),性能更高但可能产生饥饿
在公平模式下,等待时间最长的线程优先获得许可,避免线程长期得不到执行。
基本上就这些。使用 Semaphore 可以有效控制并发访问,避免资源竞争。注意确保每次 acquire() 后都有对应的 release(),建议放在 finally 块中,防止死锁或资源泄露。不复杂但容易忽略细节。


