轉自:
http://www.java265.com/JavaCourse/202204/3184.html
下文筆者講述java中Semaphore類的詳解說明,如下所示:
Semaphore簡介
Semaphore(中文翻譯:信號量)
我們常用于控制訪問某一資源的執行緒個數,
使用這種方式可使大家按照一定的規則訪問某一資源
Semaphore的原理:
通過使用計數器來控制對某一資源的訪問
當計數器大于0,則允許訪問
當計數器為0時,則拒絕訪問
計數器中的計數作為允許訪問共享資源的許可
即:訪問資源,需從信號量中授予執行緒許可
Semaphore方法
| 方法名 | 備注 |
| void acquire() | 從信號量獲取一個許可,在無可用許可前,將一直阻塞等待 |
| void acquire(int permits) | 獲取指定數目的許可,在無可用許可前,也將會一直阻塞等待 |
| boolean tryAcquire() | 從信號量嘗試獲取一個許可,當無可用許可,直接回傳false,不會阻塞 |
| boolean tryAcquire(int permits) | 嘗試獲取指定數目的許可,當無可用許可直接回傳false |
| boolean tryAcquire(int permits, long timeout, TimeUnit unit) | 在指定的時間內嘗試從信號量中獲取許可,當在指定的時間內獲取成功,回傳true,否則回傳false |
| void release() | 釋放一個許可,別忘了在finally中使用 注意:多次呼叫該方法,會使信號量的許可數增加,達到動態擴展的效果 如:初始permits為1,呼叫了兩次release,最大許可會改變為2 |
| int availablePermits() | 獲取當前信號量可用的許可 |
Semaphore建構式
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}
引數說明:
permits:初始許可數,即最大訪問執行緒數
fair:當設定為false時,創建的信號量為非公平鎖;當設定為true時,信號量是公平鎖
使用Semaphore限制登錄的最大用戶數
package com.java265.other;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class Test16 {
public static void main(String[] args) {
// 允許最大的獲取用戶的執行緒數
int slots = 8;
ExecutorService executorService = Executors.newFixedThreadPool(slots);
UserUsingSemaphore loginQueue = new UserUsingSemaphore(slots);
// 執行緒池模擬登錄
for (int i = 1; i <= slots; i++) {
final int num = i;
executorService.execute(() -> {
if (loginQueue.tryAcquire()) {
System.out.println("用戶:" + num + "獲取成功!");
} else {
System.out.println("用戶:" + num + "獲取失敗!");
}
});
}
executorService.shutdown();
System.out.println("當前可用許可證數:" + loginQueue.availableSlots());
// 此時已經有8個執行緒,再次獲取的時候會回傳false
if (loginQueue.tryAcquire()) {
System.out.println("獲取成功!");
} else {
System.out.println("資源已經被占滿,獲取失敗!");
}
// 有用戶釋放資源,只釋放一個資源
loginQueue.releaseAcquire();
// 再次獲取
if (loginQueue.tryAcquire()) {
System.out.println("獲取成功-2!");
} else {
System.out.println("資源已經被占滿,獲取失敗-2!");
}
// 再次獲取-會失敗,因為又沒有空余
if (loginQueue.tryAcquire()) {
System.out.println("獲取成功-3!");
} else {
System.out.println("資源已經被占滿,獲取失敗-3!");
}
}
}
/*
* 定義一個登錄佇列,用于獲取信號量
*/
class UserUsingSemaphore {
private Semaphore semaphore;
/**
* @param 設定信號量的大小
*/
public UserUsingSemaphore(int slotLimit) {
semaphore = new Semaphore(slotLimit);
}
boolean tryAcquire() {
// 獲取一個憑證
return semaphore.tryAcquire();
}
/*
* 釋放憑證
*/
void releaseAcquire() {
semaphore.release();
}
/*
* 獲取可用的憑證數量
*/
int availableSlots() {
return semaphore.availablePermits();
}
}
------運行以上代碼,將輸出以下資訊------
用戶:1獲取成功!
用戶:5獲取成功!
用戶:2獲取成功!
用戶:4獲取成功!
用戶:3獲取成功!
用戶:7獲取成功!
用戶:6獲取成功!
當前可用許可證數:1
資源已經被占滿,獲取失敗!
獲取成功-2!
資源已經被占滿,獲取失敗-3!
用戶:8獲取成功!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/467899.html
標籤:Java
