您好,登錄后才能下訂單哦!
本篇內容主要講解“怎么使用CyclicBarrier”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么使用CyclicBarrier”吧!
CyclicBarrier與CountDownLatch比較相似,CountDownLatch的await方法阻塞線程,直到足夠數量的countDown后所有線程重新開始運行,而CyclicBarrier的await則是阻塞線程,當await的數量達到指定數量是所有阻塞線程直接重新開始運行。
CyclicBarrier有兩個構造方法“public CyclicBarrier(int parties, Runnable barrierAction)“與”public CyclicBarrier(int parties)”。其中parties是在調用await方法次數達到的最大次數,當達到就會喚醒所有阻塞線程。barrierAction是當正常喚醒所有線程前優先執行的任務。
屬性主要有以下幾個:
//這兩個屬性用來保持同步和線程阻塞與喚醒
private final ReentrantLock lock = new ReentrantLock();
private final Condition trip = lock.newCondition();
//每個輪的最大await的次數
private final int parties;
//當線程被喚醒前可以優先一些執行任務,可以設置在這里
private final Runnable barrierCommand;
//這是一個內部類,通過它實現CyclicBarrier重復利用,每當await達到最大次數的時候,就會新建一個放到這里,表示進入了下一個輪回,里面只有一個boolean型屬性,用來表示當前輪回是否有線程中斷,
private Generation generation = new Generation();
//當前輪回剩余await的次數,初始值是parties,沒調用一次await方法就減一,當減到0就喚醒線程。
private int count;
這幾個屬性可能在這里還不清楚他們的作用,不過接下來下一節就清楚了。
CyclicBarrier最主要的方法就是await方法了,而await方法調用的是一個私有方法dowait,dowait的方法源碼較長這里就不貼出來了,通過流程圖分析下如下圖:
我把dowait方法主要分成3步:
第一步是記錄當前代generation,并且count減一。第二、三步是根據count減少后的值進行判斷。
第二步是count等于0的情況,表明調用await方法達到預設次數,應該喚醒其他線程,不過步驟是優先運行設置的barrierCommand任務,然后創建下一代generation,表示后面調用await會進入下一個輪回,最后才是喚醒所有線程。
第三步是最后一步,也是發生阻塞線程的地方,當count不等于0則會直接阻塞線程,await支持阻塞指定時間,這里就沒有特別說明了。當線程被喚醒,這里喚醒有兩種情況:一種是第二步最后的喚醒,應該重新new了一個generation,所以可以讓線程跳出循環,不在阻塞線程。一種是因為有一個線程拋出中斷異常而喚醒,中斷異常會修改g的broken為true,使當前線程拋出指定的異常。
到此,相信大家對“怎么使用CyclicBarrier”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。