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

Java中的Semaphore信號量深入解析

 更新時間:2023年11月20日 10:21:02   作者:?薄情痞子?  
這篇文章主要介紹了Java中的Semaphore信號量深入解析,Semaphore是Java里面另外一個基本的并發(fā)工具包類,主要的的作用是用來保護共享資源的訪問的,也就是僅僅允許一定數(shù)量的線程訪問共享資源,需要的朋友可以參考下

Semaphore信號量

Semaphore是Java里面另外一個基本的并發(fā)工具包類,主要的的作用是用來保護共享資源的訪問的,也就是僅僅允許一定數(shù)量的線程訪問共享資源。

Semaphore維護了有限數(shù)量的許可證,只有得到了許可證的線程才能進行共享資源的訪問,如果得不到許可證,說明當前共享資源的訪問已經(jīng)達到最大限制,所以會掛起當前線程,直到前面的線程處理完任務之后,把許可證歸還,后面排隊的線程才有機會獲取,然后處理任務。

這里面有兩個注意點:

(1)大多數(shù)時候使用Semaphore都應該是公平模式,默認是非公平模式,如果需要公平模式可以在構(gòu)造函數(shù)里面指定,公平性可以 保證先進先出,不會有線程饑餓問題出現(xiàn),非公平模式,不保證順序,吞吐量會更好一些。

(2)共享資源的訪問,一般指的是讀取,而不是更新,這里面不要做對共享變量的修改,除非你使用同步塊來保證。

下面我們來看下Semaphore的構(gòu)造方法:

Semaphore(int permits) //非公平模式指定最大允許訪問許可證數(shù)量
Semaphore(int permits, boolean fair)//可以通過第二個參數(shù)控制是否使用公平模

一些常用的方法:

acquire() //申請獲取一個許可證,如果沒有許可證,就阻塞直到能夠獲取或者被打斷
availablePermits() // 返回當前有多少個有用的許可證數(shù)量hasQueuedThreads()//查詢是否有線程正在等待獲取許可證
drainPermits()//獲得并返回所有立即可用的許可證數(shù)量
getQueuedThreads()//返回一個List包含當前可能正在阻塞隊列里面所有線程對象
getQueueLength()//返回當前可能在阻塞獲取許可證線程的數(shù)量
hasQueuedThreads()//查詢是否有線程正在等待獲取許可證
isFair()//返回是否為公平模式
reducePermits(int reduction)//減少指定數(shù)量的許可證
reducePermits(int reduction)//釋放一個許可證
release(int permits)//釋放指定數(shù)量的許可證
tryAcquire()//非阻塞的獲取一個許可證

無論是Semaphore還是CountDonwLatch或者是CyclicBarrier,其實我們都可以通過Lock接口+Condition條件隊列功能來模擬實現(xiàn),但是不夠抽象所以才出現(xiàn)了AQS這個抽象的面向開發(fā)者同步框架,比如這個Semaphore,我們看下如何使用Lock實現(xiàn):

public class SemaphoreDemo2 {
 
    private final Lock lock=new ReentrantLock(true);
    private final Condition condition=lock.newCondition();
    private int permit;
    public SemaphoreDemo2(int permit) {
        this.permit=permit;
    }
 
 
    private void acquire(){
 
        lock.lock();
        try{
            if(permit==0){
                condition.await();//如果超過限制,就進入條件阻塞隊列
            }
            System.out.println(Thread.currentThread().getName()+"  獲得資源 .... ");
             permit--;
 
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
 
    }
 
 
    private void  release(){
        lock.lock();
        try{
            permit++;
            condition.signalAll(); //每當有一個釋放令牌,就喚醒所有等待的線程
        }finally {
            lock.unlock();
        }
 
 
    }
 
 
}

下面我們看一下簡單的使用例子:

Semaphore semaphore=new Semaphore(3);
 
        Runnable runnable=new Runnable() {
            @Override
            public void run() {
                try {
                    semaphore.acquire();
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " 訪問資源......");
                    semaphore.release();
            }
        };
 
        for (int i = 0; i < 5; i++) {
            Thread thread=new Thread(runnable);
            thread.start();
        }
 
        Thread.sleep(3000);

輸出結(jié)果:

Thread-0 訪問資源......
Thread-1 訪問資源......
Thread-2 訪問資源......
Thread-4 訪問資源......
Thread-3 訪問資源......

注意上面的例子只有3個許可證,我們運行了5個線程,所以同時最多只能運行3個線程,另外兩個會阻塞直到前面的線程歸還了許可證。

Semaphore底層原理:

Semaphore底層與CountDownLatch類似都是通過AQS的共享鎖機制來實現(xiàn)的,指定的數(shù)量會設置到AQS里面的state里面,然后對于每一個 調(diào)用acquire方法線程,state都會減去一,如果state等于0,那么調(diào)用該方法的線程會被添加到同步隊列里面,同時使用 LockSupport.park方法掛起等待,知道有線程調(diào)用了release方法,會對state加1,然后喚醒共享隊列里面的線程,注意這里如果是 公平模式,就直接喚醒下一個等待線程即可,如果是非公平模式就允許新加入的線程與已有的線程進行競爭,誰先得到就是誰的,如果新加入的 競爭失敗,就會走公平模式進入隊列排隊。

總結(jié):

本文主要介紹了并發(fā)工具包Semaphore其主要作用來限制對于共享資源的訪問,接著我們又介紹了其特點,使用及注意事項,然后又給出了使用其他同步工具Lock+Condition實現(xiàn)的Semaphore

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

相關(guān)文章

  • Java集合系列之LinkedHashMap源碼分析

    Java集合系列之LinkedHashMap源碼分析

    這篇文章主要為大家詳細介紹了Java集合系列之LinkedHashMap源碼分析,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • RabbitMQ消息有效期與死信的處理過程

    RabbitMQ消息有效期與死信的處理過程

    利用DLX,當消息在一個隊列中變成死信?(dead?message)?之后,它能被重新publish到另一個Exchange,這個Exchange就是DLX,本文重點給大家介紹RabbitMQ消息有效期與死信的相關(guān)知識,感興趣的朋友跟隨小編一起看看吧
    2022-03-03
  • 基于java的opencv開發(fā)過程詳解

    基于java的opencv開發(fā)過程詳解

    這篇文章主要介紹了基于java的opencv開發(fā)過程詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Java中對象數(shù)組的使用方法詳解

    Java中對象數(shù)組的使用方法詳解

    這篇文章主要介紹了Java中對象數(shù)組的使用方法,結(jié)合實例形式分析了java對象數(shù)組的功能、定義、初始化與相關(guān)使用技巧,需要的朋友可以參考下
    2019-08-08
  • Java學習隨記之多線程編程

    Java學習隨記之多線程編程

    這篇文章主要介紹了Java中的多線程編程的相關(guān)知識,文中的示例代碼介紹詳細,對我們的學習或工作有一定的價值,感興趣的小伙伴可以了解一下
    2021-12-12
  • Java使用云片API發(fā)送短信驗證碼

    Java使用云片API發(fā)送短信驗證碼

    這篇文章主要介紹了Java使用云片API發(fā)送短信驗證碼,主要用的是Java實現(xiàn)短信驗證碼。需要的朋友可以參考下
    2017-02-02
  • Java.lang.NullPointerException的錯誤解決

    Java.lang.NullPointerException的錯誤解決

    Java中NullPointerException是一種常見的運行時異常,通常發(fā)生在嘗試調(diào)用null對象的方法或訪問其屬性時,具有一定的參考價值,感興趣的可以了解一下
    2024-09-09
  • springboot websocket集群(stomp協(xié)議)連接時候傳遞參數(shù)

    springboot websocket集群(stomp協(xié)議)連接時候傳遞參數(shù)

    這篇文章主要介紹了springboot websocket集群(stomp協(xié)議)連接時候傳遞參數(shù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-07-07
  • servlet監(jiān)聽實現(xiàn)統(tǒng)計在線人數(shù)功能 附源碼下載

    servlet監(jiān)聽實現(xiàn)統(tǒng)計在線人數(shù)功能 附源碼下載

    這篇文章主要為大家詳細介紹了servlet監(jiān)聽統(tǒng)計在線人數(shù)的實現(xiàn)方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Java使用代理進行網(wǎng)絡連接方法示例

    Java使用代理進行網(wǎng)絡連接方法示例

    這篇文章主要介紹了Java使用代理進行網(wǎng)絡連接方法示例,內(nèi)容十分詳細,需要的朋友可以參考下。
    2017-09-09

最新評論