最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的Semaphore如何使用

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

簡(jiǎn)介

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

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

簡(jiǎn)述實(shí)現(xiàn)原理

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

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

方法介紹

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

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

案例分析

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

@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();
    }
}
  • 運(yùn)行結(jié)果

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

適用場(chǎng)景

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

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

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

相關(guān)文章

  • Java?多線程并發(fā)ReentrantLock

    Java?多線程并發(fā)ReentrantLock

    這篇文章主要介紹了Java?多線程并發(fā)ReentrantLock,Java?提供了?ReentrantLock?可重入鎖來提供更豐富的能力和靈活性,感興趣的小伙伴可以參考一下
    2022-06-06
  • SpringBoot測(cè)試類注入Bean失敗的原因及分析

    SpringBoot測(cè)試類注入Bean失敗的原因及分析

    SpringBoot 2.2版本前后測(cè)試類有所變化,2.2版本之后使用JUnit 5,導(dǎo)入注解@SpringBootTest和@Test來自junit.jupiter.api包;而2.2版本之前使用JUnit 4,需要額外導(dǎo)入@RunWith注解來自junit.runner包,無論哪個(gè)版本,都需確保測(cè)試類和啟動(dòng)類的包名一致
    2024-09-09
  • 修改Springboot默認(rèn)序列化工具Jackson配置的實(shí)例代碼

    修改Springboot默認(rèn)序列化工具Jackson配置的實(shí)例代碼

    這篇文章主要介紹了如何修改Springboot默認(rèn)序列化工具Jackson的配置,當(dāng)Spring容器中存在多個(gè)同類型的Bean時(shí),默認(rèn)情況下最后一個(gè)創(chuàng)建的Bean將作為首選Bean,文中通過代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • Java遞歸和迭代區(qū)別詳細(xì)介紹

    Java遞歸和迭代區(qū)別詳細(xì)介紹

    這篇文章主要給大家介紹了關(guān)于Java中的迭代和遞歸有什么區(qū)別,文中介紹的非常詳細(xì),感興趣的同學(xué)可以參考閱讀
    2023-04-04
  • Java中集合LinkedList的原理與使用方法

    Java中集合LinkedList的原理與使用方法

    這篇文章主要給大家介紹了關(guān)于Java中集合LinkedList的原理與使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • 一篇文章輕松了解SpringBoot配置高級(jí)

    一篇文章輕松了解SpringBoot配置高級(jí)

    大家都知道SpringBoot擁有良好的基因,還能簡(jiǎn)化編碼、配置、部署、監(jiān)控,也是現(xiàn)在面試必問的一個(gè)點(diǎn),下面這篇文章主要給大家介紹了如何通過一篇文章輕松了解SpringBoot配置高級(jí)的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • java web手寫實(shí)現(xiàn)分頁功能

    java web手寫實(shí)現(xiàn)分頁功能

    這篇文章主要為大家詳細(xì)介紹了java web手寫實(shí)現(xiàn)分頁功能的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • Spring Security方法鑒權(quán)的實(shí)現(xiàn)

    Spring Security方法鑒權(quán)的實(shí)現(xiàn)

    在Spring Security中,主要有兩種鑒權(quán)方式,一個(gè)是基于web請(qǐng)求的鑒權(quán),一個(gè)是基于方法的鑒權(quán),本文就來介紹一下Spring Security方法鑒權(quán)的實(shí)現(xiàn),感興趣的可以了解一下
    2023-12-12
  • springboot+mybatis配置clickhouse實(shí)現(xiàn)插入查詢功能

    springboot+mybatis配置clickhouse實(shí)現(xiàn)插入查詢功能

    這篇文章主要介紹了springboot+mybatis配置clickhouse實(shí)現(xiàn)插入查詢功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • springboot自定義注解RateLimiter限流注解技術(shù)文檔詳解

    springboot自定義注解RateLimiter限流注解技術(shù)文檔詳解

    文章介紹了限流技術(shù)的概念、作用及實(shí)現(xiàn)方式,通過Spring AOP攔截方法、緩存存儲(chǔ)計(jì)數(shù)器,結(jié)合注解、枚舉、異常類等核心組件,實(shí)現(xiàn)對(duì)訪問頻率的控制,旨在防止攻擊、保障系統(tǒng)穩(wěn)定、提升用戶體驗(yàn)及節(jié)約成本
    2025-07-07

最新評(píng)論

腾冲县| 临高县| 来安县| 阿坝县| 乐清市| 大兴区| 洛阳市| 淮滨县| 禄丰县| 渝中区| 枝江市| 治县。| 北流市| 陆河县| 古丈县| 孟州市| 安阳市| 公主岭市| 泸定县| 江油市| 阳新县| 铜山县| 兴隆县| 彭州市| 万载县| 凤凰县| 广平县| 德保县| 浑源县| 南部县| 宜都市| 贡嘎县| 张北县| 海伦市| 漯河市| 白河县| 巴南区| 屏边| 乐清市| 商河县| 京山县|