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 例項可用的許可證數量。

hazelcast_data_structures.htm
廣告
© . All rights reserved.