適用 2022.1 【更新時間 2022-4-29】 引言 由於IDEA在2021.2.2以後我們不能再使用重置大法白嫖了。 為了打擊破解,Jetbrains煞費苦心,這次採用了JB賬號登陸,通過授權認證獲取免費試用資格(所以之前的無限重置的插件在今後的新版本中,將無法使用),以下整理了一個免JB註 ...
轉自:
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獲取成功!