Java 信号量(Semaphore) 深入理解
简介
Semaphore,信号量,是一种用于控制对公共资源访问的计数信号装置。信号量管理着一组动态资源的使用,它通过一个计数器限制同时访问资源的线程数量。当计数器大于零时,线程可以访问资源,计数器递减;当计数器为零时,请求资源的线程进入等待状态,直到计数器大于零。
这种机制非常适合用于限制对资源的并发访问数,比如数据库连接、线程池等。
Semaphore 基础概念
Semaphore 可以设定一个许可证数量,用于表示可以访问的资源数目。当线程访问共享资源时,需要先从 Semaphore 处获取许可证,访问完毕后归还许可证。此外,Semaphore 也能实现公平性,即按照请求顺序分配许可证。
Java 的 Semaphore 位于 java.util.concurrent
包中,提供了一个灵活的信号量实现。
Semaphore 的使用方法
构造函数
Java 的 Semaphore 提供了两种构造函数:
Semaphore(int permits)
: 创建具有指定许可证数量的 Semaphore,非公平模式。Semaphore(int permits, boolean fair)
: 第二个参数为布尔值,指示是否使用公平模式。
Semaphore semaphore = new Semaphore(3); // 非公平模式
Semaphore fairSemaphore = new Semaphore(3, true); // 公平模式
常用方法
void acquire() throws InterruptedException
: 获取一个许可证,若无可用许可证,则线程进入等待。void release()
: 归还一个许可证。int availablePermits()
: 返回当前可用的许可证数量。boolean tryAcquire()
: 尝试获取一个许可证,若获取成功则返回 true,否则返回 false。
Semaphore 常见实践
限制对资源的访问
假设我们需要限制同时访问某个服务的线程数:
import java.util.concurrent.Semaphore;
public class Service {
private final Semaphore semaphore = new Semaphore(5);
public void performAction() {
try {
semaphore.acquire();
// 执行业务逻辑
System.out.println(Thread.currentThread().getName() + " is accessing the service.");
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
semaphore.release();
}
}
}
实现简单连接池
下面是一个简单的数据库连接池实现,用于限制并发访问数据库连接的数量:
import java.sql.Connection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Semaphore;
public class ConnectionPool {
private final ArrayBlockingQueue<Connection> pool;
private final Semaphore semaphore;
public ConnectionPool(int size) {
this.pool = new ArrayBlockingQueue<>(size);
this.semaphore = new Semaphore(size);
// 初始化连接池,向队列中添加 Connection 对象
}
public Connection getConnection() throws InterruptedException {
semaphore.acquire();
return pool.take();
}
public void releaseConnection(Connection connection) {
pool.offer(connection);
semaphore.release();
}
}
Semaphore 最佳实践
- 选择合适的公平策略:非公平的 Semaphore 通常具有更高的吞吐量,但公平策略能避免线程饥饿,需要根据具体需求选择。
- 确保许可证的释放:在 finally 块中释放许可证,以确保即使发生异常也能正确释放。
- 避免过多等待线程:许可证过少可能导致大量线程长期等待,降低系统性能,需要合理设置初始许可证数量。
小结
Java Semaphore 是一个强大的并发工具,能够有效地限制对共享资源的并发访问。通过本文的介绍,我们深入了解了 Semaphore 的基本概念、使用方法、常见实践以及最佳实践。在实际开发中,合理应用 Semaphore 可以大大提升系统的稳定性与可靠性。
参考资料
- Java Documentation: Semaphore
- 《Java Concurrency in Practice》 — Brian Goetz
- Baeldung: Introduction to Semaphores in Java
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能