- Hazelcast 教程
- Hazelcast - 首页
- Hazelcast - 简介
- Hazelcast - 设置
- Hazelcast - 第一个应用程序
- Hazelcast - 配置
- 设置多节点实例
- Hazelcast - 数据结构
- Hazelcast - 客户端
- Hazelcast - 序列化
- Hazelcast 高级特性
- Hazelcast - Spring 集成
- Hazelcast - 监控
- Map Reduce & 聚合
- Hazelcast - 集合监听器
- 常见问题 & 性能技巧
- Hazelcast 有用资源
- Hazelcast - 快速指南
- Hazelcast - 有用资源
- Hazelcast - 讨论
Hazelcast - ISemaphore
java.util.concurrent.Semaphore 通过在 JVM 的多线程环境中提供有限的访问权限来支持同步。
听起来很像锁,对吧?但是锁和信号量之间有两个主要区别:
信号量没有所有权。它可以被一个线程获取,并由另一个线程释放。锁与线程绑定。它需要由同一个线程释放和获取。
信号量支持根据**req**和可用许可证,允许一个或多个线程进入临界区。
类似地,ISemaphore 提供了 Java Semaphore 的分布式版本。它提供类似的功能:acquire(获取),release(释放)。
但是 ISemaphore 和 Java Semaphore 之间的一个主要区别是:Java Semaphore 提供了对单个 JVM 中线程的临界区的保护,而 ISemaphore 则为单个 JVM 和多个 JVM 中的线程提供同步。
ISemaphore 只有一个同步备份,这意味着,如果我们有一个设置,例如运行 5 个 JVM,则只有两个 JVM 会持有此信号量。
获取许可证,释放许可证
示例
让我们在**三个 JVM**上执行以下代码。该代码应该打印已获取信号量的线程数。我们有 2 个许可证,这意味着一次只允许两个线程进入 if 块。
public static void main(String... args) throws IOException, InterruptedException { //initialize hazelcast instance HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance(); // create a lock ISemaphore hzSemaphore = hazelcast.getSemaphore("semaphore_1"); IAtomicLong activeThreads = hazelcast.getAtomicLong("threads"); hzSemaphore.init(2); for(int i=0; i< 10; i++) { if(hzSemaphore.tryAcquire(2000, TimeUnit.MILLISECONDS)); { System.out.println("Thread count: " + activeThreads.incrementAndGet()); Thread.sleep(2000); hzSemaphore.release(); activeThreads.decrementAndGet(); } } System.exit(0); }
代码的输出显示我们有 1 或 2 个活动线程,这正是我们根据许可证设置为 2 所期望的。
最佳实践
如果拥有许可证的成员宕机,则许可证会自动释放,使其可供其他线程获取。
避免使用信号量的 acquire() 方法,因为它是一个阻塞调用,可能会导致死锁。最好使用带有超时的 tryAcquire() 方法来避免阻塞。
常用方法
序号 | 函数名称和描述 |
---|---|
1 | acquire() 如果可用,则获取许可证。如果不可用,它会无限期等待直到许可证可用。 |
2 | release() 释放已获取的许可证。 |
3 | tryAcquire(long time, TimeUnit unit) 尝试在给定的时间窗口内获取许可证。如果获取许可证,则返回 true,否则返回 false。 |
4 | availablePermits() 返回此 ISemaphore 实例可用的许可证数量。 |