<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          理解ReentrantLock的公平鎖和非公平鎖

          共 1501字,需瀏覽 4分鐘

           ·

          2021-10-15 04:06

          點擊關注,與你共同成長!




          學習AQS的時候,了解到AQS依賴于內(nèi)部的FIFO同步隊列來完成同步狀態(tài)的管理,當前線程獲取同步狀態(tài)失敗時,同步器會將當前線程以及等待狀態(tài)等信息構(gòu)造成一個Node對象并將其加入到同步隊列,同時會阻塞當前線程,當同步狀態(tài)釋放時,會把首節(jié)點中的線程喚醒,使其再次嘗試獲取同步狀態(tài)。

          這時,我有了一個疑問,AQS的同步隊列是FIFO的,就是先來排隊的先走。那怎么實現(xiàn)非公平鎖呢?查閱了一些資料,總算知道了。

          首先從公平鎖開始看起。

          ReentrantLock 的公平鎖

          ReentrantLock 默認采用非公平鎖,除非在構(gòu)造方法中傳入?yún)?shù) true 。

          ????//默認
          ????public?ReentrantLock()?{
          ????????sync?=?new?NonfairSync();
          ????}
          ????//傳入true?or?false
          ????public?ReentrantLock(boolean?fair)?{
          ????????sync?=?fair???new?FairSync()?:?new?NonfairSync();
          ????}

          公平鎖的 lock 方法:

          ????static?final?class?FairSync?extends?Sync?{
          ????????final?void?lock()?{
          ????????????acquire(1);
          ????????}
          ????????//?AbstractQueuedSynchronizer.acquire(int?arg)
          ????????public?final?void?acquire(int?arg)?{
          ????????????if?(!tryAcquire(arg)?&&
          ????????????????acquireQueued(addWaiter(Node.EXCLUSIVE),?arg))
          ????????????????selfInterrupt();
          ????????}
          ????????protected?final?boolean?tryAcquire(int?acquires)?{
          ????????????final?Thread?current?=?Thread.currentThread();
          ????????????int?c?=?getState();
          ????????????if?(c?==?0)?{
          ????????????????// 1. 和非公平鎖相比,這里多了一個判斷:是否有線程在等待
          ????????????????if?(!hasQueuedPredecessors()?&&
          ????????????????????compareAndSetState(0,?acquires))?{
          ????????????????????setExclusiveOwnerThread(current);
          ????????????????????return?true;
          ????????????????}
          ????????????}
          ????????????else?if?(current?==?getExclusiveOwnerThread())?{
          ????????????????int?nextc?=?c?+?acquires;
          ????????????????if?(nextc?0)
          ????????????????????throw?new?Error("Maximum?lock?count?exceeded");
          ????????????????setState(nextc);
          ????????????????return?true;
          ????????????}
          ????????????return?false;
          ????????}
          ????}

          我們可以看到,在注釋1的位置,有個!hasQueuedPredecessors()條件,意思是說當前同步隊列沒有前驅(qū)節(jié)點(也就是沒有線程在等待)時才會去compareAndSetState(0, acquires)使用CAS修改同步狀態(tài)變量。所以就實現(xiàn)了公平鎖,根據(jù)線程發(fā)出請求的順序獲取鎖。

          非公平鎖的lock方法

          ????static?final?class?NonfairSync?extends?Sync?{
          ????????final?void?lock()?{
          ????????????//?2.?和公平鎖相比,這里會直接先進行一次CAS,成功就返回了
          ????????????if?(compareAndSetState(0,?1))
          ????????????????setExclusiveOwnerThread(Thread.currentThread());
          ????????????else
          ????????????????acquire(1);
          ????????}
          ????????//?AbstractQueuedSynchronizer.acquire(int?arg)
          ????????public?final?void?acquire(int?arg)?{
          ????????????if?(!tryAcquire(arg)?&&
          ????????????????acquireQueued(addWaiter(Node.EXCLUSIVE),?arg))
          ????????????????selfInterrupt();
          ????????}
          ????????protected?final?boolean?tryAcquire(int?acquires)?{
          ????????????return?nonfairTryAcquire(acquires);
          ????????}
          ????}
          ????/**
          ????*?Performs?non-fair?tryLock.??tryAcquire?is?implemented?in
          ????*?subclasses,?but?both?need?nonfair?try?for?trylock?method.
          ????*/

          ????final?boolean?nonfairTryAcquire(int?acquires)?{
          ????????final?Thread?current?=?Thread.currentThread();
          ????????int?c?=?getState();
          ????????if?(c?==?0)?{
          ????????????//3.這里也是直接CAS,沒有判斷前面是否還有節(jié)點。
          ????????????if?(compareAndSetState(0,?acquires))?{
          ????????????????setExclusiveOwnerThread(current);
          ????????????????return?true;
          ????????????}
          ????????}
          ????????else?if?(current?==?getExclusiveOwnerThread())?{
          ????????????int?nextc?=?c?+?acquires;
          ????????????if?(nextc?0)?//?overflow
          ????????????????throw?new?Error("Maximum?lock?count?exceeded");
          ????????????setState(nextc);
          ????????????return?true;
          ????????}
          ????????return?false;
          ????}

          非公平鎖的實現(xiàn)在剛進入lock方法時會直接使用一次CAS去嘗試獲取鎖,不成功才會到acquire方法中,如注釋2。而在nonfairTryAcquire方法中并沒有判斷是否有前驅(qū)節(jié)點在等待,直接CAS嘗試獲取鎖,如注釋3。由此實現(xiàn)了非公平鎖。

          總結(jié)

          非公平鎖和公平鎖的兩處不同

          • 非公平鎖在調(diào)用 lock 后,首先就會調(diào)用 CAS 進行一次搶鎖,如果這個時候恰巧鎖沒有被占用,那么直接就獲取到鎖返回了。

          • 非公平鎖在 CAS 失敗后,和公平鎖一樣都會進入到 tryAcquire 方法,在 tryAcquire 方法中,如果發(fā)現(xiàn)鎖這個時候被釋放了(state == 0),非公平鎖會直接 CAS 搶鎖,但是公平鎖會判斷等待隊列是否有線程處于等待狀態(tài),如果有則不去搶鎖,乖乖排到后面。

          公平鎖和非公平鎖就這兩點區(qū)別,如果這兩次 CAS 都不成功,那么后面非公平鎖和公平鎖是一樣的,都要進入到阻塞隊列等待喚醒。

          相對來說,非公平鎖會有更好的性能,因為它的吞吐量比較大。當然,非公平鎖讓獲取鎖的時間變得更加不確定,可能會導致在阻塞隊列中的線程長期處于饑餓狀態(tài)。

          原文鏈接:https://www.jianshu.com/p/2ada27eee90b


          搭建深度學習環(huán)境之一:安裝Docker

          累計連續(xù)簽到設計和實現(xiàn)

          翻譯翻譯:什么叫架構(gòu)?


          以上,便是今天的分享,希望大家喜歡,覺得內(nèi)容不錯的,歡迎「分享」「」或者點擊「在看」支持,謝謝各位。

          瀏覽 53
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  影音先锋最新av资源 | 黄片毛片在线观看 | 亚欧综合在线 | 一级a免一级a做免费线看中文字幕 | 三级麻豆 |