CyclicBarrier原始碼解析

寒武沒有紀發表於2018-10-10

CyclicBarrier 基於可重入鎖 ReentrantLockCondition 共同實現。

  • parties:設定多少個執行緒或者任務等待至 barrier 狀態
  • barrierAction:設定指定執行緒全部到達 barrier 狀態時會執行的任務
public CyclicBarrier(int parties) {
}

public CyclicBarrier(int parties, Runnable barrierAction) {
}

分析 await 方法

public int await() throws InterruptedException, BrokenBarrierException {
    try {
        return dowait(false, 0L);
    } catch (TimeoutException toe) {
        throw new Error(toe); // cannot happen
    }
}
private int dowait(boolean timed, long nanos)
    throws InterruptedException, BrokenBarrierException,
           TimeoutException {
    final ReentrantLock lock = this.lock;
    lock.lock(); // 獲取鎖
    try {
        final Generation g = generation;
        // 當前generation已損壞,則丟擲異常
        if (g.broken) 
            throw new BrokenBarrierException();
        // 如果當前執行緒被中斷,則通過breakBarrier終止CyclicBarrier,喚醒CyclicBarrier中所有等待執行緒
        if (Thread.interrupted()) {
            breakBarrier();
            throw new InterruptedException();
        }

        int index = --count; // 計數值自減
        if (index == 0) {  // 計數值為0表示已經有parties個執行緒到達barrier
            boolean ranAction = false;
            try {
                final Runnable command = barrierCommand; // 第二個構造方法中傳遞的到達barrier需要執行的任務
                if (command != null)
                    command.run(); // 執行到達barrier的任務
                ranAction = true;
                nextGeneration(); // 喚醒所有等待執行緒並更新generation
                return 0;
            } finally {
                if (!ranAction)
                    breakBarrier();
            }
        }

        // loop until tripped, broken, interrupted, or timed out
        // 執行緒處於阻塞狀態,直到 parties個執行緒到達barrier 或 當前執行緒被中斷 或 超時,執行緒才繼續執行
        for (;;) {
            try {
                // 沒有設定超時時間,使用await等待;否則使用awaitNanos等待
                if (!timed)
                    trip.await();
                else if (nanos > 0L)
                    nanos = trip.awaitNanos(nanos);
            } catch (InterruptedException ie) {
                // 如果執行緒被中斷,則喚醒所有等待執行緒
                if (g == generation && ! g.broken) {
                    breakBarrier();
                    throw ie;
                } else {
                    // We're about to finish waiting even if we had not
                    // been interrupted, so this interrupt is deemed to
                    // "belong" to subsequent execution.
                    Thread.currentThread().interrupt();
                }
            }

            if (g.broken)
                throw new BrokenBarrierException();

            if (g != generation)
                return index;
            // 如果設定了超時等待 且 超時時間已到,則喚醒所有等待執行緒
            if (timed && nanos <= 0L) {
                breakBarrier();
                throw new TimeoutException();
            }
        }
    } finally {
        lock.unlock(); // 釋放鎖
    } 
}

相關文章