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