Hazelcast - ISemaphore
java.util.concurrent.Semaphore 通过在 JVM 的多线程环境中工作时提供有限的访问来支持同步。
听起来很像一把锁,对吧? 但锁和信号量有两个主要区别 −
信号量没有所有权。 它可以由一个线程获取并由另一个线程释放。 锁与一根线相连。 需要由同一个线程释放和获取。
信号量支持基于可用许可的 req 将一个或多个线程中的 1 个进入临界区。
同样,ISemaphore 提供了 Java Semaphore 的分布式版本。 ISemaphore 提供了 Java Semaphore 的分布式版本。 它提供类似的功能:获取、释放。
但 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() 以避免阻塞。
有用的方法
Sr.No | 函数名称 & 描述 |
---|---|
1 | acquire() 获得许可证(如果有)。 如果不可用,它将无限期地等待,直到许可证可用。 |
2 | release() 释放已获得的许可证。 |
3 | tryAcquire(long time, TimeUnit unit) 尝试在给定的时间窗口内获得许可。 如果获得许可则返回 true,否则返回 false。 |
4 | availablePermits() 返回此 ISemaphore 实例可用的许可数量 |
hazelcast_data_structures.html