天天看點

Java并發程式設計之信号量 Semaphore

Java并發程式設計之信号量 Semaphore

作者: 西魏陶淵明

部落格: ​​https://blog.springlearn.cn/​​

西魏陶淵明

莫笑少年江湖夢,誰不少年夢江湖

🚀 知識快讀

​Semaphore​

​​ 翻譯過來就是信号量, 其根本原理就是基于 ​

​CAS​

​​ 共享鎖的一種實作。舉一個例子。

假設停車場隻有三個車位,一開始三個車位都是空的。這時如果同時來了五輛車,看門人允許其中三輛不受阻礙的進入,然後放下車攔,剩下的車則必須在入口等待,此後來的車也都不得不在入口處等待。這時,有一輛車離開停車場,看門人得知後,打開車攔,放入一輛,如果又離開兩輛,則又可以放入兩輛,如此往複。

那麼上面的這個例子可以這樣了解,資源一共有3個, 即三個車位。如何來控制這5輛汽車,來合理的使用這3個資源呢?

​​

​Semaphore​

​ 可以這樣來定義。

// 1. 定一個信号量,聲明有3個資源。使用公平模式線程将會按到達的順序(FIFO)執行(也就是等待時間最長的先執行),如果是非公平,則可以後請求的有可能排在隊列的頭部。
Semaphore semp = new Semaphore(3);
// 2. 擷取1個許可 - 最大允許3個進入,一但超過就讓其等待,除非已經釋放
semp.acquire();  
// 3. 釋放1個許可 
semp.release(); 
// 4. 擷取1許可,失敗就傳回,不等待
semp.tryAcquire();  
// 5. 擷取2許可,失敗就傳回,不等待
semp.tryAcquire(2);  
// 6. 不允許被中斷
semp.acquireUninterruptibly();      

知識點1: Fair & NoFair

  • 預設構造不公平模式, 誰來申請資源,就先嘗試擷取資源。排隊的要等到沒有資源進來申請才能繼續申請
public Semaphore(int permits) {
        sync = new NonfairSync(permits);
    }

    public Semaphore(int permits, boolean fair) {
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }      

知識點2: 申請資源

  • acquire() 擷取1個資源,擷取不到就等待,如果線程中斷,會直接中斷。
  • acquire(2) 擷取2個資源,擷取不到就等待,如果線程中斷,會直接中斷。
  • tryAcquire() 擷取1個資源,擷取不到就傳回​

    ​false​

    ​,如果線程中斷,會直接中斷。
  • acquireUninterruptibly() 擷取1個資源,擷取不到就等待,不會關心線程中斷。

知識點3: 釋放資源

  • release() 釋放一個資源
  • release(2) 釋放兩個資源

知識點4: 其他API

  • availablePermits() 目前資源數量
  • drainPermits() 擷取目前資源數量,并将剩餘資源清零,直接指派0
  • reducePermits(2) 将資源數量,扣減2個
  • isFair() 是否公平
  • hasQueuedThreads() 是否還有線程等待
  • getQueueLength() 還有多少線程等待
  • getQueuedThreads() 擷取所有的線程集合