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