信号量通过许可机制控制并发访问,Java中Semaphore类提供acquire()和release()方法实现线程同步,支持公平与非公平模式,限制同时访问资源的线程数。

在Java中,信号量(Semaphore)是一种用于控制多个线程对共享资源访问的同步工具。它通过维护一组许可来限制同时访问特定资源的线程数量。使用信号量可以有效实现线程间的协调与同步。
理解信号量的基本机制
信号量内部维护一定数量的许可(permits)。线程在访问资源前必须先获取许可,成功获取后才能执行操作;操作完成后需释放许可,以便其他线程使用。如果当前没有可用许可,试图获取的线程将被阻塞,直到有线程释放许可为止。
Java中的 Semaphore 类位于 java.util.concurrent 包中,支持公平和非公平两种模式:
- 非公平模式:线程获取许可时不保证顺序,可能造成某些线程长时间等待
- 公平模式:按照请求顺序分配许可,避免饥饿问题
创建和使用信号量
通过构造函数初始化信号量,指定许可数量。常用方法包括 acquire() 和 release()。
立即学习“Java免费学习笔记(深入)”;
1、请上传下载到的淘宝客系统安装包并上传到空间根目录中进行解压,解压后将网站文件移动到根目录的位置,然后访问 /install 进行安装。您也可以在本地解压,并以二进制方式将程序上传至您的网站空间。 2、同意启科网络电子商务系统安装协议进入下一步。 3、如果系统检测环境通过,则会提示输入您的数据库服务器地址(一般为本机,即127.0.0.1或者localhost)、数据库账号、数据库密码、数据库名
示例代码:
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 = 1; i <= 5; i++) {
new Thread(new Worker(i)).start();
}
}
static class Worker implements Runnable {
private int id;
Worker(int id) {
this.id = id;
}
public void run() {
try {
System.out.println("线程 " + id + " 正在尝试获取许可...");
semaphore.acquire(); // 获取许可
System.out.println("线程 " + id + " 获得许可,开始工作");
Thread.sleep(2000); // 模拟工作
System.out.println("线程 " + id + " 工作完成,释放许可");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
semaphore.release(); // 释放许可
}
}
}
}
应用场景与注意事项
信号量适用于以下场景:
- 限制数据库连接池中的并发连接数
- 控制对有限硬件资源的访问(如打印机)
- 实现流量控制或限流功能
使用时注意:
- 确保每次 acquire() 后都有对应的 release(),建议放在 finally 块中
- 信号量不依赖锁,不会发生死锁,但仍需防止因异常导致许可未释放
- 可根据需要选择公平性策略,但公平模式可能影响吞吐量









