欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中的Semaphore如何使用

 更新時間:2022年06月27日 14:51:22   作者:生命猿于運動  
Semaphore實際上是一種共享鎖,因為它允許多個線程并發(fā)獲取共享的資源,在Semaphore對象創(chuàng)建時必須設(shè)置可用令牌的初始數(shù)量permits,用于控制并發(fā)時同時獲取資源權(quán)限的線程數(shù)量,這篇文章主要介紹了Java中的Semaphore如何使用,需要的朋友可以參考下

簡介

semaphore中文意思既是信號量,它的主要功能就是用來控制某個資源同時被訪問的線程數(shù)。

為了控制某塊資源的并發(fā)訪問量時,可以使用Semaphore對象中的acquire()方法獲取訪問令牌,如果Semaphore對象訪問令牌已發(fā)完,那么當(dāng)前獲取令牌的線程將會進(jìn)入阻塞,帶其他線程進(jìn)行release()釋放令牌時,當(dāng)前線程才有機會獲得令牌從而擁有訪問權(quán)限。

簡述實現(xiàn)原理

Semaphore實際上是一種共享鎖,因為它允許多個線程并發(fā)獲取共享的資源。在Semaphore對象創(chuàng)建時必須設(shè)置可用令牌的初始數(shù)量permits,用于控制并發(fā)時同時獲取資源權(quán)限的線程數(shù)量。在Semaphore類中繼承了同步隊列AbstractQueuedSynchronizer,在此類中有個屬性state用于標(biāo)記當(dāng)前并發(fā)的隊列數(shù),也就是獲取令牌的線程數(shù),那么在進(jìn)行acquire()的時候,就會嘗試獲取共享鎖,獲取鎖成功后state值將加1,如果state值已經(jīng)達(dá)到permits時就表示令牌已派發(fā)完,當(dāng)前線程將進(jìn)入阻塞狀態(tài),待其他線程進(jìn)行release()state值將減1,此時就會從隊列中獲取頭部線程進(jìn)行喚醒讓其獲得令牌進(jìn)行資源訪問。

如下圖,仔細(xì)查看源碼就會發(fā)現(xiàn)Semaphore實際上就是重寫了AbstractQueuedSynchronizer中的tryAcquireShared()tryReleaseShared()方法來實現(xiàn)的。

方法介紹

  • Semaphore重載了兩個構(gòu)造函數(shù),其一是Semaphore(int permits)直接指定令牌數(shù),默認(rèn)為非公平鎖;其二是Semaphore(int permits,boolean fair),fair參數(shù)即表示線程搶占令牌的公平性,true為公平鎖,否則為非公平鎖。
  • acquire()無參表示默認(rèn)獲取一個令牌,acquire(int permits)表示獲取指定permits數(shù)量的令牌數(shù),如果令牌不夠,則當(dāng)前線程進(jìn)入阻塞狀態(tài)。

tryAcquire()無參表示嘗試獲取一個令牌,該方法是非阻塞的,所以如果令牌數(shù)不夠獲取失敗返回false,否則就返回true;同時也重載了方法tryAcquire(int permits)指定獲取令牌數(shù),tryAcquire(int permits, long timeout, TimeUnit unit)在有效時間內(nèi)嘗試獲取指定數(shù)量的令牌數(shù),如果超時仍未獲取到令牌則返回false,否則返回true。 release同上支持無參與帶參指定釋放令牌數(shù)的方法。 drainPermits()獲取剩下的可用令牌。 hasQueuedThread()用于判斷當(dāng)前Semaphare實例中是否存在等待獲取令牌的線程。

案例分析

分析一下下面這段簡短的代碼,首先是創(chuàng)建一個信號量為5的Semaphore對象,然后在創(chuàng)建一個線程池(這里為了演示方便,實際開發(fā)中不建議使用此線程池創(chuàng)建),利用for循環(huán)并發(fā)運行100個線程,當(dāng)線程運行時優(yōu)先獲取一個令牌,在線程中的業(yè)務(wù)代碼里我們做了1秒的休眠,為了展示等待獲取令牌的效果,在延遲1秒執(zhí)行完業(yè)務(wù)代碼時進(jìn)行令牌釋放,后續(xù)的線程才能逐個被喚醒獲取令牌訪問共享資源。

@Slf4j
public class SemaphoreDemo {

    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(5);
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 100; i++) {
            executorService.execute(() -> {
                try {
                    semaphore.acquire();
                    log.info("成功獲取令牌");
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    log.info("釋放令牌");
                    semaphore.release();
                }
            });
        }
        executorService.shutdown();
    }
}
  • 運行結(jié)果

由下圖運行結(jié)果可見,100個線程并發(fā)并不是一次性都執(zhí)行完的,而是要等待前面的線程釋放令牌后等待的線程才可以獲取令牌進(jìn)行業(yè)務(wù)代碼的運行。

適用場景

Semaphore主要是運用在多線程環(huán)境中對某一些共享資源的訪問量限制,防止多個線程并發(fā)訪問同一資源,可能會導(dǎo)致大多數(shù)線程獲取資源時都需要進(jìn)行加鎖,那如果是獲取數(shù)據(jù)庫中的數(shù)據(jù),那么就可以緩解數(shù)據(jù)庫的壓力。

另一種情況是用于多線程運行的一個流量限制,一般情況下我們可能會通過線程池做一步線程數(shù)的控制,但是某些業(yè)務(wù)為了減輕CPU的負(fù)擔(dān),還是會做一些同時運行線程數(shù)的限制。

到此這篇關(guān)于Java中的Semaphore如何使用的文章就介紹到這了,更多相關(guān)Semaphore使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MyBatis中的模糊查詢語句

    MyBatis中的模糊查詢語句

    這篇文章主要介紹了MyBatis中的模糊查詢語句的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Arthas在線java進(jìn)程診斷工具在線調(diào)試神器詳解

    Arthas在線java進(jìn)程診斷工具在線調(diào)試神器詳解

    Arthas是 Alibaba 開源的Java診斷工具,深受開發(fā)者喜愛。這篇文章主要介紹了Arthas在線java進(jìn)程診斷工具 在線調(diào)試神器,需要的朋友可以參考下
    2021-11-11
  • Java中的LinkedHashMap源碼詳解

    Java中的LinkedHashMap源碼詳解

    這篇文章主要介紹了Java中的LinkedHashMap源碼詳解,LinkedHashMap的實現(xiàn)方式是將所有的Entry節(jié)點鏈入一個雙向鏈表,并且它的底層數(shù)據(jù)結(jié)構(gòu)是HashMap,因此,LinkedHashMap具有HashMap的所有特性,但在存取元素的細(xì)節(jié)實現(xiàn)上有所不同,需要的朋友可以參考下
    2023-09-09
  • Java基礎(chǔ)之異常處理操作示例

    Java基礎(chǔ)之異常處理操作示例

    這篇文章主要介紹了Java基礎(chǔ)之異常處理操作,涉及java異常捕獲、拋出異常、自定義異常處理相關(guān)操作技巧,需要的朋友可以參考下
    2019-08-08
  • LCN分布式事務(wù)解決方案詳解

    LCN分布式事務(wù)解決方案詳解

    這篇文章主要介紹了LCN分布式事務(wù)解決方案詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • tio-boot框架整合ehcache實現(xiàn)過程示例

    tio-boot框架整合ehcache實現(xiàn)過程示例

    這篇文章主要為大家介紹了tio-boot框架整合ehcache實現(xiàn)過程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • 微服務(wù)mybatis typehandler使用詳解(就這一篇夠了)

    微服務(wù)mybatis typehandler使用詳解(就這一篇夠了)

    TypeHandler是MyBatis框架的核心組件,實現(xiàn)數(shù)據(jù)庫表字段類型和Java 數(shù)據(jù)類型之間的相互轉(zhuǎn)換,本文介紹通過實例代碼mybatis typehandler使用,感興趣的朋友一起看看吧
    2024-02-02
  • springbooot整合dynamic?datasource數(shù)據(jù)庫密碼加密方式

    springbooot整合dynamic?datasource數(shù)據(jù)庫密碼加密方式

    這篇文章主要介紹了springbooot整合dynamic?datasource?數(shù)據(jù)庫密碼加密方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Spring Boot實現(xiàn)對文件進(jìn)行壓縮下載功能

    Spring Boot實現(xiàn)對文件進(jìn)行壓縮下載功能

    在Web應(yīng)用中,文件下載功能是一個常見的需求,特別是當(dāng)你需要提供用戶下載各種類型的文件時,本文將演示如何使用Spring Boot框架來實現(xiàn)一個簡單而強大的文件下載功能,需要的朋友跟隨小編一起學(xué)習(xí)吧
    2023-09-09
  • 圖文詳解OkHttp的超時時間

    圖文詳解OkHttp的超時時間

    HTTP是現(xiàn)代應(yīng)用常用的一種交換數(shù)據(jù)和媒體的網(wǎng)絡(luò)方式,高效地使用HTTP能讓資源加載更快,節(jié)省帶寬,OkHttp是一個高效的HTTP客戶端,下面這篇文章主要給大家介紹了關(guān)于OkHttp超時時間的相關(guān)資料,需要的朋友可以參考下
    2021-10-10

最新評論