原始碼解析-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() 喚醒所有等待的節點