Java中的Semaphore信號(hào)量詳解
1、介紹
Semaphore(信號(hào)量)是用來控制同時(shí)訪問特定資源的線程數(shù)量,通過協(xié)調(diào)各個(gè)線程以保證合理地使用公共資源。
Semaphore通過使用計(jì)數(shù)器來控制對(duì)共享資源的訪問。 如果計(jì)數(shù)器大于0,則允許訪問。
如果為0,則拒絕訪問。 計(jì)數(shù)器所計(jì)數(shù)的是允許訪問共享資源的許可。 因此,要訪問資源,必須從信號(hào)量中授予線程許可。
2、主要方法
- void acquire() :從信號(hào)量獲取一個(gè)許可,如果無可用許可前將一直阻塞等待,
- void acquire(int permits) :獲取指定數(shù)目的許可,如果無可用許可前也將會(huì)一直阻塞等待
- boolean tryAcquire():從信號(hào)量嘗試獲取一個(gè)許可,如果無可用許可,直接返回false,不會(huì)阻塞
- boolean tryAcquire(int permits): 嘗試獲取指定數(shù)目的許可,如果無可用許可直接返回false
- boolean tryAcquire(int permits, long timeout, TimeUnit unit): 在指定的時(shí)間內(nèi)嘗試從信號(hào)量中獲取許可,如果在指定的時(shí)間內(nèi)獲取成功,返回true,否則返回false
- void release():釋放一個(gè)許可,別忘了在finally中使用,注意:多次調(diào)用該方法,會(huì)使信號(hào)量的許可數(shù)增加,達(dá)到動(dòng)態(tài)擴(kuò)展的效果,如:初始permits為1,調(diào)用了兩次release,最大許可會(huì)改變?yōu)?
- int availablePermits(): 獲取當(dāng)前信號(hào)量可用的許可
Semaphore構(gòu)造函數(shù)
public Semaphore(int permits) { sync = new NonfairSync(permits); } public Semaphore(int permits, boolean fair) { sync = fair ? new FairSync(permits) : new NonfairSync(permits); }
- permits 初始許可數(shù),也就是最大訪問線程數(shù)
- fair 當(dāng)設(shè)置為false時(shí),創(chuàng)建的信號(hào)量為非公平鎖;當(dāng)設(shè)置為true時(shí),信號(hào)量是公平鎖
3、Semaphore登錄限流示例
在以下示例中,實(shí)現(xiàn)一個(gè)簡單的登錄隊(duì)列,通過Semaphore來限制系統(tǒng)中的用戶數(shù):
public static void main(String[] args) { //允許最大的登錄數(shù) int slots=10; ExecutorService executorService = Executors.newFixedThreadPool(slots); LoginQueueUsingSemaphore loginQueue = new LoginQueueUsingSemaphore(slots); //線程池模擬登錄 for (int i = 1; i <= slots; i++) { final int num=i; executorService.execute(()->{ if (loginQueue.tryLogin()){ System.out.println("用戶:"+num+"登錄成功!"); }else { System.out.println("用戶:"+num+"登錄失?。?); } }); } executorService.shutdown(); System.out.println("當(dāng)前可用許可證數(shù):"+loginQueue.availableSlots()); //此時(shí)已經(jīng)登錄了10個(gè)用戶,再次登錄的時(shí)候會(huì)返回false if (loginQueue.tryLogin()){ System.out.println("登錄成功!"); }else { System.out.println("系統(tǒng)登錄用戶已滿,登錄失?。?); } //有用戶退出登錄 loginQueue.logout(); //再次登錄 if (loginQueue.tryLogin()){ System.out.println("登錄成功!"); }else { System.out.println("系統(tǒng)登錄用戶已滿,登錄失敗!"); } }
class LoginQueueUsingSemaphore{ private Semaphore semaphore; /** * * @param slotLimit */ public LoginQueueUsingSemaphore(int slotLimit){ semaphore=new Semaphore(slotLimit); } boolean tryLogin() { //獲取一個(gè)憑證 return semaphore.tryAcquire(); } void logout() { semaphore.release(); } int availableSlots() { return semaphore.availablePermits(); } }
運(yùn)行結(jié)果:
到此這篇關(guān)于Java中的Semaphore信號(hào)量詳解的文章就介紹到這了,更多相關(guān)Semaphore信號(hào)量內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)企業(yè)發(fā)放的獎(jiǎng)金根據(jù)利潤提成問題
這篇文章主要介紹了請(qǐng)利用數(shù)軸來分界,定位。注意定義時(shí)需把獎(jiǎng)金定義成長整型,需要的朋友可以參考下2017-02-02淺談java web中常用對(duì)象對(duì)應(yīng)的實(shí)例化接口
下面小編就為大家?guī)硪黄獪\談java web中常用對(duì)象對(duì)應(yīng)的實(shí)例化接口。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02mybatis-plus使用generator實(shí)現(xiàn)逆向工程
mybatis-plus-generator在3.5.0以及以后的版本使用新的方式逆向生成代碼,本文主要介紹了mybatis-plus使用generator實(shí)現(xiàn)逆向工程,具有一定的參考價(jià)值,感興趣的可以了解一下2022-05-05SpringBoot統(tǒng)一數(shù)據(jù)返回的方法實(shí)現(xiàn)
在前后端交互過程中,為了便于數(shù)據(jù)處理,后端數(shù)據(jù)需要進(jìn)行統(tǒng)一封裝返回給前端,這種做法不僅方便前后端溝通,降低了溝通成本,還有助于項(xiàng)目的統(tǒng)一維護(hù)和后端技術(shù)部門的規(guī)范制定,本文就來介紹一下2024-10-10java8 集合 多字段 分組 統(tǒng)計(jì)個(gè)數(shù)代碼
這篇文章主要介紹了java8 集合 多字段 分組 統(tǒng)計(jì)個(gè)數(shù)代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08Java的方法和this關(guān)鍵字如何理解與應(yīng)用
Java語言中的“方法”(Method)在其他語言當(dāng)中也可能被稱為“函數(shù)”(Function)。對(duì)于一些復(fù)雜的代碼邏輯,如果希望重復(fù)使用這些代碼,并且做到“隨時(shí)任意使用”,那么就可以將這些代碼放在一個(gè)大括號(hào){}當(dāng)中,并且起一個(gè)名字。使用代碼的時(shí)候,直接找到名字調(diào)用即可2021-10-10