CyclicBarrier源碼走讀

并發工具類中,我們簡單了解了CyclicBarrier,接下來走讀下代碼看看其是如何實現的,代碼基于JDK1.7。

代碼走讀

重要的屬性

從上圖可以看出CyclicBarrier是基于可重入鎖的條件隊列實現的,parties代表同一代的線程數,count代表同一代等待的線程數,調用await()方法一次,count減1,直到為0。接下來看看dowait()方法(await()方法其實調用dowait()方法)。這個是CyclicBarrier最核心的方法。

dowait()方法流程
  1. 柵欄破壞,拋出異常。

  2. 線程中斷,主要看breakBarrier()方法,這個方法也很重要。

  3. 同一代等待的線程數減1.

  4. 當同一代等待的線程數為0時,首先執行barrierCommand的run()方法,注意:等待的線程沒有執行。

  5. 當同一代等待的線程數為0時,調用nextGeneration()方法。

breakBarrier()

喚醒等待的線程,即CyclicBarrier的線程中斷后,等待的線程還是要執行的。

nextGeneration()

喚醒等待的線程,即首先執行barrierCommand的run()方法,然后等待的線程執行;同時new Generation(),即產生新的一代,這里可以看出復用。

  1. 線程添加到循環隊列。

  2. 出現異常后執行喚醒等待線程繼續執行,即:超時后barrierCommand的run()方法不執行,等待線程仍然執行。

總結:CyclicBarrier基于可重入鎖的條件隊列實現的,可以復用的柵欄。

例子

public class CyclicBarrierDemo {

    private static int SIZE = 5;
    private static CyclicBarrier cb;

    public static void main(String[] args) {

        cb = new CyclicBarrier(SIZE, new Runnable() {
            public void run() {
                System.out.println("CyclicBarrier's parties is: " + cb.getParties());
            }
        });


        // 新建10個任務
        for (int i = 0; i < 10; i++)
            new InnerThread().start();
    }

    static class InnerThread extends Thread {
        public void run() {
            try {
                System.out.println(Thread.currentThread().getName() + " wait for CyclicBarrier.");

                // 將cb的參與者數量加1
                cb.await();
                // cb的參與者數量等于5時,才繼續往后執行
                System.out.println(Thread.currentThread().getName() + " continued.");
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

//執行結果
Thread-0 wait for CyclicBarrier.
Thread-1 wait for CyclicBarrier.
Thread-2 wait for CyclicBarrier.
Thread-3 wait for CyclicBarrier.
Thread-4 wait for CyclicBarrier.
CyclicBarrier's parties is: 5
Thread-5 wait for CyclicBarrier.
Thread-4 continued.
Thread-0 continued.
Thread-3 continued.
Thread-2 continued.
Thread-1 continued.
Thread-6 wait for CyclicBarrier.
Thread-7 wait for CyclicBarrier.
Thread-8 wait for CyclicBarrier.
Thread-9 wait for CyclicBarrier.
CyclicBarrier's parties is: 5
Thread-9 continued.
Thread-5 continued.
Thread-7 continued.
Thread-8 continued.
Thread-6 continued.
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。