1. 程式人生 > 實用技巧 >原始碼解析-Semaphore

原始碼解析-Semaphore

建立 Semaphore 例項的時候,需要一個引數 permits,

這個基本上可以確定是設定給 AQS 的 state 的,

然後每個執行緒呼叫 acquire 的時候,執行 state = state - 1,

release 的時候執行 state = state + 1,

當然,acquire 的時候,如果 state = 0,說明沒有資源了,需要等待其他執行緒 release。

基本操作

1.建立Semaphore物件,初始化permits

2. semaphore.acquire() 佔用一個位置

3. semaphore.release() 取消一個位置

Semaphore原理是AQS 可以理解成 就是多個物件共持有的一把鎖,達到permits數量 再想爭搶鎖就要等待,持有鎖的物件釋放。也區分公平鎖非公平鎖競爭原則

原始碼解析:

1. new Semaphore()

沒啥好說的 初始化設定AQS的state

2. acquire(int permits) 佔用幾個空位的資源

acquireSharedInterruptibly() 老中斷處理了

if (tryAcquireShared(arg) < 0) //說明佔位失敗  要麼是沒那麼多位置給你佔  要麼是CAS失敗了

3. tryAcquireShared() 非公平鎖的實現

死迴圈(){

獲取當前的state值;

remaining = state - 想要佔位數;

if(如果想要佔位數>state總數 或者CAS成功 ){

  返回剩餘位數;

}

}

4. doAcquireSharedInterruptibly() 佔位失敗,加入到阻塞佇列

將節點封裝成Node 加入到阻塞佇列

for( 死迴圈){

  判斷前直接點是不是頭節點;

  如果前置節點是頭節點,嘗試去搶佔位置,

  搶佔成功了,大吉大利 佇列中刪除節點,結束;

  搶失敗了 掛起等待喚醒。

}

finally{

  如果中途被中斷了 就退出爭搶 不玩了;

}

5. relase() 釋放資源

6. tryReleaseShared() 嘗試釋放共享資源 改state值

for(死迴圈){

  獲取當前state值;

  next = state + 要釋放的位置數;

  CAS交換

}

7. doReleaseShared() 喚醒所有等待的節點