Java并發(fā)編程之Semaphore詳解
概念
- 信號(hào)量Semaphore一般用來表示可用資源的個(gè)數(shù),相當(dāng)于一個(gè)計(jì)數(shù)器,可類比生活中停車場牌子上面顯示的停車場剩余車位數(shù)量。
- 當(dāng)有車開進(jìn)去的時(shí)候, 就相當(dāng)于申請(qǐng)一個(gè)可用資源,可用車位就 -1 (這個(gè)稱為信號(hào)量的 P 操作) 當(dāng)有車開出來的時(shí)候, 就相當(dāng)于釋放一個(gè)可用資源, 可用車位就 +1 (這個(gè)稱為信號(hào)量的 V 操作)
- 如果計(jì)數(shù)器的值已經(jīng)為 0 了,還嘗試申請(qǐng)資源,就會(huì)阻塞等待,直到有其他線程釋放資源(計(jì)數(shù)器的值是大于等于0的)
默認(rèn)構(gòu)造方法
public Semaphore(int permits){}
信號(hào)量:permits
重要方法
//申請(qǐng)資源,計(jì)數(shù)器值=0,則阻塞 public void acquire() throws InterruptedException {} //釋放資源 public void release() {}
1、類Semaphore的構(gòu)造函數(shù)permits 是許可的意思,代表同一時(shí)間,最多允許permits執(zhí)行acquire() 和release() 之間的代碼。
例如:
Semaphore semaphore = new Semaphore(1);
- 2、方法acquire(n) 的功能是每調(diào)用1次此方法,就消耗掉n個(gè)許可。
- 3、方法release(n) 的功能是每調(diào)用1次此方法,就動(dòng)態(tài)添加n個(gè)許可。
- 4、方法acquireUnnterruptibly()作用是是等待進(jìn)入acquire() 方法的線程不允許被中斷。
- 5、方法availablePermits() 返回Semaphore對(duì)象中當(dāng)前可以用的許可數(shù)。
- 6、方法drainPermits() 獲取并返回所有的許可個(gè)數(shù),并且將可用的許可重置為0
- 7、方法 getQueueLength() 的作用是取得等待的許可的線程個(gè)數(shù)
- 8、方法 hasQueueThreads() 的作用是判斷有沒有線程在等待這個(gè)許可
- 9、公平和非公平信號(hào)量:有些時(shí)候獲取許可的的順序與線程啟動(dòng)的順序有關(guān),這是的信號(hào)量就要分為公平和非公平的。所謂的公平信號(hào)量是獲得鎖的順序與線程啟動(dòng)的順序有關(guān),但不代表100%獲得信號(hào)量,僅僅是在概率上能保證,而非公平信號(hào)量就是無關(guān)的。
例如:
Semaphore semaphore = new Semaphore(1,false);
- False:表示非公平信號(hào)量,即線程啟動(dòng)的順序與調(diào)用semaphore.acquire() 的順序無關(guān),也就是線程先啟動(dòng)了并不代表先獲得 許可。
- True:公平信號(hào)量,即線程啟動(dòng)的順序與調(diào)用semaphore.acquire() 的順序有關(guān),也就是先啟動(dòng)的線程優(yōu)先獲得許可。
- 10、方法tryAcquire() 的作用是嘗試獲取1個(gè)許可。如果獲取不到則返回false,通常與if語句結(jié)合使用,其具有無阻塞的特點(diǎn)。無阻塞的特點(diǎn)可以使不至于在同步處于一直持續(xù)等待的狀態(tài)。
- 11、方法tryAcquire(n) 的作用是嘗試獲取n個(gè)許可,如果獲取不到則返回false
- 12、方法tryAcquire(long timeout,TimeUnit unit)的作用是在指定的時(shí)間內(nèi)嘗試獲取1個(gè)許可,如果獲取不到則返回false
- 13、方法tryAcquire(int permits,long timeout,TimeUnit unit) 的作用是在指定的時(shí)間內(nèi)嘗試獲取n 個(gè)許可,如果獲取不到則返回false
- 14、多進(jìn)路-多處理-多出路:允許多個(gè)線程同時(shí)處理任務(wù)
測試使用
import java.util.concurrent.Semaphore; public class Test { public static void main(String[] args) { Semaphore semaphore = new Semaphore(3); Runnable runnable = new Runnable() { @Override public void run() { try { System.out.println("準(zhǔn)備申請(qǐng)資源"); semaphore.acquire(); System.out.println("申請(qǐng)資源成功"); // 申請(qǐng)到資源之后休眠1秒 Thread.sleep(1000); semaphore.release(); // 釋放資源 System.out.println("釋放資源完畢"); } catch (InterruptedException e) { e.printStackTrace(); } } }; // 創(chuàng)建15個(gè)線程,讓這 15 個(gè)線程來分別去嘗試申請(qǐng)資源 for (int i = 0; i < 15; i++) { Thread t = new Thread(runnable); t.start(); } } }
運(yùn)行結(jié)果如下:
可以看到,由于資源數(shù)為3,所以前3個(gè)線程申請(qǐng)資源后很容易成功,而之后的線程就沒有資源可以申請(qǐng)了,只能等到前3個(gè)線程把資源釋放出來后再申請(qǐng)
信號(hào)量相當(dāng)于是鎖的升級(jí)版本,鎖只能控制一個(gè)資源的有無,而信號(hào)量可以控制很多個(gè)資源的有無
到此這篇關(guān)于Java并發(fā)編程之concurrent包中的Semaphore詳解的文章就介紹到這了,更多相關(guān)Java的Semaphore信號(hào)量內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot關(guān)閉druid的頁面和添加密碼驗(yàn)證方式
這篇文章主要介紹了SpringBoot關(guān)閉druid的頁面和添加密碼驗(yàn)證方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05Java中stream.map和stream.forEach的區(qū)別
本文主要介紹了Java中stream.map和stream.forEach的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08java.io.NotSerializableException異常的問題及解決
這篇文章主要介紹了java.io.NotSerializableException異常的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12mybatis查詢返回Map<String,Object>類型的講解
這篇文章主要介紹了mybatis查詢返回Map<String,Object>類型的講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06對(duì)比Java中的Comparable排序接口和Comparator比較器接口
Comparable和Comparator接口都可用作普通意義上對(duì)象間的比大小,但兩個(gè)接口在實(shí)例化方面的用法不盡相同,接下來我們就來詳細(xì)對(duì)比Java中的Comparable排序接口和Comparator比較器接口2016-05-05解決SpringBoot中的Scheduled單線程執(zhí)行問題
在一次SpringBoot中使用Scheduled定時(shí)任務(wù)時(shí),發(fā)現(xiàn)某一個(gè)任務(wù)出現(xiàn)執(zhí)行占用大量資源,會(huì)導(dǎo)致其他任務(wù)也執(zhí)行失敗,這篇文章主要介紹了SpringBoot中的Scheduled單線程執(zhí)行問題及解決方法,需要的朋友可以參考下2022-06-06Java 比較接口comparable與comparator區(qū)別解析
這篇文章主要介紹了Java 比較接口comparable與comparator區(qū)別解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10