AQS.doReleaseShared
生活随笔
收集整理的這篇文章主要介紹了
AQS.doReleaseShared
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
共享鎖的釋放和獨占鎖的釋放有一定的差別
前面喚醒鎖的邏輯和獨占鎖是一樣,先判斷頭結點是不是SIGNAL狀態,如果是,則修改為0,并且喚醒頭結點的下一個節點
PROPAGATE: 標識為PROPAGATE狀態的節點,是共享鎖模式下的節點狀態,處于這個狀態下的節點,會對線程的喚醒進行傳播
private void doReleaseShared() { for (;;) { Node h = head; if (h != null && h != tail) { int ws = h.waitStatus; if (ws == Node.SIGNAL) { if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0)) continue; // loop to recheck cases unparkSuccessor(h); } // 這個 CAS 失敗的場景是:執行到這里的時候,剛好有一個節點入隊,入隊會將這個 ws 設置為 -1 else if (ws == 0 && !compareAndSetWaitStatus(h, 0, Node.PROPAGATE)) continue; // loop on failed CAS } // 如果到這里的時候,前面喚醒的線程已經占領了 head,那么再循環// 通過檢查頭節點是否改變了,如果改變了就繼續循環 if (h == head) // loop if head changed break; } }h == head:說明頭節點還沒有被剛剛用?unparkSuccessor 喚醒的線程(這里可以理解為?ThreadB)占有,此時 break 退出循環。
h != head:頭節點被剛剛喚醒的線程(這里可以理解為?ThreadB)占有,那么這里重新進入下一輪循環,喚醒下一個節點(這里是 ThreadB )。我們知道,等到?ThreadB 被喚醒后,其實是會主動喚醒 ThreadC...
?
總結
以上是生活随笔為你收集整理的AQS.doReleaseShared的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CountDownLatch.count
- 下一篇: doAcquireSharedInter