JDK 8 CyclicBarrier 源码详解(详细注释版)

JDK 8 CyclicBarrier 源码详解(详细注释版)

1. 类定义和基本属性

public class CyclicBarrier {
    
    /**
     * CyclicBarrier的核心同步控制对象
     * 使用ReentrantLock和Condition实现同步
     * 这种设计使得CyclicBarrier具有可重入性和条件等待能力
     * 
     * 设计巧妙之处:
     * - 使用ReentrantLock提供互斥访问
     * - 使用Condition实现线程等待和唤醒
     * - 支持可重入性,简化实现
     * - 提供灵活的等待机制
     */
    private final ReentrantLock lock = new ReentrantLock();

    /**
     * 等待条件对象
     * 用于协调参与屏障的线程
     * 当线程到达屏障点时等待,直到所有线程都到达
     * 
     * Condition的作用:
     * - 提供比Object.wait/notify更灵活的等待机制
     * - 支持超时等待和可中断等待
     * - 与ReentrantLock紧密结合
     * - 提供更好的性能和可控性
     */
    private final Condition trip = lock.newCondition();

    /**
     * 屏障的参与线程数量
     * 这是屏障的基本配置,不可更改
     * 必须有指定数量的线程调用await()才能突破屏障
     * 
     * 设计考虑:
     * - final修饰确保不可变性
     * - 必须为正数
     * - 决定了屏障的突破条件
     */
    private final int parties;

    /**
     * 屏障突破时执行的回调命令
     * 当所有线程都到达屏障点时执行
     * 执行在最后一个到达线程所在的线程中
     * 
     * 回调特点:
     * - 在最后一个线程中执行
     * - 可以为null(不执行任何操作)
     * - 如果抛出异常,会影响所有等待线程
     * - 提供屏障突破后的处理机会
     */
    private final Runnable barrierCommand;

    /**
     * 当前的屏障生成号
     * 用于区分不同的屏障周期
     * 每次屏障突破后generation会更新
     * 
     * Generation的作用:
     * - 标识当前屏障周期
     * - 支持屏障的可重用性
     * - 避免过期的等待线程被错误唤醒
     * - 提供屏障状态管理
     */
    private Generation generation = new Generation();

    /**
     * Generation内部类
     * 用于标识屏障的代数/周期
     * 每次屏障突破都会创建新的Generation对象
     * 
     * 设计目的:
     * - 区分不同的屏障周期
     * - 避免过期等待线程的问题
     * - 支持屏障的可重用性
     * - 提供简单的状态管理
     */
    private static class Generation {
        /**
         * 屏障是否被破坏的标志
         * 如果为true,表示屏障处于破坏状态
         * 破坏状态下的await()调用会抛出BrokenBarrierException
         * 
         * 破坏原因:
         * - 线程被中断
         * - 超时
         * - 回调命令抛出异常
         * - 手动调用reset()
         */
        boolean broken = false;
    }

    /**
     * 当前还在等待的线程数量
     * 这是CyclicBarrier的核心状态变量
     * 随着线程的到达而递减
     * 
     * 计数过程:
     * 1. 初始值等于parties
     * 2. 每个线程调用await()时减1
     * 3. 当减到0时,所有等待线程被唤醒
     * 4. 屏障突破后重置为parties
     * 
     * 线程安全性:
     * - 通过ReentrantLock保护
     * - 保证计数操作的原子性
     * - 避免竞态条件
     */
    private int count;

    /**
     * 默认构造方法(私有)
     * 仅供内部使用,创建指定parties和barrierCommand的CyclicBarrier
     * 
     * 初始化过程:
     * 1. 验证parties参数的有效性
     * 2. 设置parties和barrierCommand字段
     * 3. 初始化count为parties
     * 4. 创建Generation对象
     * 
     * @param parties 参与线程数量
     * @param barrierCommand 屏障突破时执行的回调命令
     */
    private CyclicBarrier(int parties, Runnable barrierCommand) {
        if (parties <= 0) throw new IllegalArgumentException();
        this.parties = parties;
        this.count = parties;
        this.barrierCommand = barrierCommand;
    }

    /**
     * 指定参与线程数量的构造方法
     * @param parties 参与线程数量
     * 
     * 构造过程:
     * 1. 验证parties参数必须为正数
     * 2. 调用私有构造方法
     * 3. 不设置回调命令(为null)
     * 
     * 参数说明:
     * - parties必须大于0
     * - parties决定了屏障的突破条件
     * - 没有回调命令
     * 
     * @throws IllegalArgumentException 如果parties小于等于0
     */
    public CyclicBarrier(int parties) {
        this(parties, null);
    }

    /**
     * 指定参与线程数量和回调命令的构造方法
     * @param parties 参与线程数量
     * @param barrierAction 屏障突破时执行的回调命令
     * 
     * 构造过程:
     * 1. 验证parties参数必须为正数
     * 2. 调用私有构造方法
     * 3. 设置回调命令
     * 
     * 参数说明:
     * - parties必须大于0
     * - barrierAction可以为null
     * - 回调命令在最后一个线程中执行
     * 
     * @throws IllegalArgumentException 如果parties小于等于0
     */
    public CyclicBarrier(int parties, Runnable barrierAction) {
        this(parties, barrierAction);
    }

2. 核心等待方法(详细注释)

    /**
     * 等待所有线程到达屏障点
     * 当前线程会阻塞直到所有参与线程都调用此方法
     * 
     * 等待过程:
     * 1. 获取ReentrantLock锁
     * 2. 检查屏障是否被破坏
     * 3. 减少等待线程计数
     * 4. 如果不是最后一个线程,进入等待状态
     * 5. 如果是最后一个线程,执行回调命令并唤醒所有等待线程
     * 6. 释放ReentrantLock锁
     * 
     * 破坏处理:
     * - 如果屏障被破坏,抛出BrokenBarrierException
     * - 如果线程被中断,抛出InterruptedException
     * - 如果超时,抛出TimeoutException
     * 
     * 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(等待时间)
     * 线程安全性:完全线程安全
     * 
     * @return 当前线程在所有线程中的到达顺序(0表示最后一个到达)
     * @throws InterruptedException 如果线程被中断
     * @throws BrokenBarrierException 如果屏障被破坏
     */
    public int await() throws InterruptedException, BrokenBarrierException {
        try {
            return dowait(false, 0L); // 调用内部等待方法,不使用超时
        } catch (TimeoutException toe) {
            throw new Error(toe); // 不可能发生的异常
        }
    }

    /**
     * 等待所有线程到达屏障点(带超时)
     * 当前线程会阻塞直到所有参与线程都调用此方法或超时
     * 
     * 超时处理:
     * 1. 获取ReentrantLock锁
     * 2. 检查屏障是否被破坏
     * 3. 减少等待线程计数
     * 4. 如果不是最后一个线程,进入等待状态
     * 5. 在指定时间内等待,超时则破坏屏障
     * 6. 如果是最后一个线程,执行回调命令并唤醒所有等待线程
     * 7. 释放ReentrantLock锁
     * 
     * 超时后果:
     * - 超时的线程抛出TimeoutException
     * - 屏障被破坏,其他等待线程抛出BrokenBarrierException
     * - 所有后续的await()调用都会失败
     * 
     * 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(等待时间)
     * 线程安全性:完全线程安全
     * 
     * @param timeout 等待时间
     * @param unit 时间单位
     * @return 当前线程在所有线程中的到达顺序(0表示最后一个到达)
     * @throws InterruptedException 如果线程被中断
     * @throws BrokenBarrierException 如果屏障被破坏
     * @throws TimeoutException 如果等待超时
     */
    public int await(long timeout, TimeUnit unit)
        throws InterruptedException,
               BrokenBarrierException,
               TimeoutException {
        return dowait(true, unit.toNanos(timeout)); // 调用内部等待方法,使用超时
    }

    /**
     * 实际的等待方法
     * 实现CyclicBarrier的核心等待逻辑
     * 
     * 核心算法:
     * 1. 获取ReentrantLock锁保护临界区
     * 2. 检查屏障状态和线程状态
     * 3. 更新等待线程计数
     * 4. 根据情况决定等待、唤醒或破坏屏障
     * 5. 执行回调命令(如果是最后一个线程)
     * 6. 唤醒所有等待线程
     * 7. 释放锁并返回结果
     * 
     * 算法特点:
     * - 原子性:通过锁保证操作的原子性
     * - 一致性:维护屏障状态的一致性
     * - 完整性:处理各种异常情况
     * - 可重用性:屏障突破后可重复使用
     * 
     * @param timed 是否使用超时
     * @param nanos 超时时间(纳秒)
     * @return 当前线程在所有线程中的到达顺序
     * @throws InterruptedException 如果线程被中断
     * @throws BrokenBarrierException 如果屏障被破坏
     * @throws TimeoutException 如果等待超时
     */
    private int dowait(boolean timed, long nanos)
        throws InterruptedException, BrokenBarrierException,
               TimeoutException {
        final ReentrantLock lock = this.lock;
        lock.lock(); // 获取锁
        try {
            final Generation g = generation; // 获取当前代数

            // 检查屏障是否被破坏
            if (g.broken)
                throw new BrokenBarrierException();

            // 检查线程是否被中断
            if (Thread.interrupted()) {
                breakBarrier(); // 破坏屏障
                throw new InterruptedException();
            }

            int index = --count; // 减少等待线程计数
            if (index == 0) {  // 如果是最后一个线程
                boolean ranAction = false;
                try {
                    final Runnable command = barrierCommand;
                    if (command != null)
                        command.run(); // 执行回调命令
                    ranAction = true;
                    nextGeneration(); // 进入下一代
                    return 0;
                } finally {
                    if (!ranAction)
                        breakBarrier(); // 如果回调命令执行失败,破坏屏障
                }
            }

            // 不是最后一个线程,进入等待状态
            for (;;) {
                try {
                    if (!timed)
                        trip.await(); // 无限期等待
                    else if (nanos > 0L)
                        nanos = trip.awaitNanos(nanos); // 超时等待
                } catch (InterruptedException ie) {
                    if (g == generation && ! g.broken) {
                        breakBarrier(); // 破坏屏障
                        throw ie;
                    } else {
                        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(); // 释放锁
        }
    }

    /**
     * 破坏屏障
     * 将当前屏障设置为破坏状态并唤醒所有等待线程
     * 
     * 破坏过程:
     * 1. 设置当前代数的broken标志为true
     * 2. 唤醒所有在trip条件上等待的线程
     * 3. 重置等待线程计数
     * 
     * 使用场景:
     * - 线程被中断时
     * - 等待超时时
     * - 回调命令执行失败时
     * - 手动调用reset()时
     * 
     * 线程安全性:通过ReentrantLock保护
     */
    private void breakBarrier() {
        generation.broken = true;
        count = parties;
        trip.signalAll();
    }

    /**
     * 进入下一代
     * 屏障突破后调用,准备下一轮使用
     * 
     * 更新过程:
     * 1. 唤醒所有等待线程
     * 2. 重置等待线程计数为parties
     * 3. 创建新的Generation对象
     * 
     * 设计目的:
     * - 支持屏障的可重用性
     * - 区分不同的屏障周期
     * - 避免过期等待线程的问题
     * - 保持屏障状态的一致性
     * 
     * 线程安全性:通过ReentrantLock保护
     */
    private void nextGeneration() {
        trip.signalAll(); // 唤醒所有等待线程
        count = parties; // 重置等待线程计数
        generation = new Generation(); // 创建新的代数
    }

3. 查询和控制方法(详细注释)

    /**
     * 获取参与屏障的线程数量
     * 返回创建屏障时指定的参与线程数量
     * 
     * 查询过程:
     * 1. 直接返回parties字段
     * 2. parties字段是final的,线程安全
     * 
     * 时间复杂度:O(1)
     * 线程安全性:完全线程安全
     * 
     * @return 参与屏障的线程数量
     */
    public int getParties() {
        return parties;
    }

    /**
     * 查询屏障是否被破坏
     * 检查当前屏障是否处于破坏状态
     * 
     * 查询过程:
     * 1. 获取ReentrantLock锁
     * 2. 检查当前代数的broken标志
     * 3. 释放ReentrantLock锁
     * 4. 返回检查结果
     * 
     * 破坏状态说明:
     * - true:屏障被破坏,await()调用会失败
     * - false:屏障正常,可以正常使用
     * 
     * 时间复杂度:O(1)
     * 线程安全性:完全线程安全
     * 
     * @return 如果屏障被破坏返回true,否则返回false
     */
    public boolean isBroken() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return generation.broken;
        } finally {
            lock.unlock();
        }
    }

    /**
     * 获取当前还在等待的线程数量
     * 返回还需要多少线程到达屏障点
     * 
     * 查询过程:
     * 1. 获取ReentrantLock锁
     * 2. 返回当前count字段值
     * 3. 释放ReentrantLock锁
     * 
     * 注意事项:
     * - 这是一个瞬时值,可能很快过时
     * - 在高并发环境下可能不是准确值
     * - 主要用于调试和监控
     * 
     * 时间复杂度:O(1)
     * 线程安全性:完全线程安全
     * 
     * @return 当前还在等待的线程数量
     */
    public int getNumberWaiting() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return parties - count;
        } finally {
            lock.unlock();
        }
    }

    /**
     * 重置屏障
     * 将屏障恢复到初始状态
     * 
     * 重置过程:
     * 1. 获取ReentrantLock锁
     * 2. 破坏当前屏障
     * 3. 进入下一代
     * 4. 释放ReentrantLock锁
     * 
     * 使用场景:
     * - 清理屏障状态
     * - 重新开始新一轮同步
     * - 处理异常情况
     * 
     * 注意事项:
     * - 正在等待的线程会收到BrokenBarrierException
     * - 屏障恢复到初始状态
     * - 可以重新使用
     * 
     * 时间复杂度:O(1)
     * 线程安全性:完全线程安全
     */
    public void reset() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            breakBarrier();   // 破坏当前屏障
            nextGeneration(); // 进入下一代
        } finally {
            lock.unlock();
        }
    }

4. CyclicBarrier 的特点分析

核心设计理念:

/**
 * CyclicBarrier的核心设计思想:
 * 
 * 1. 屏障同步机制:
 *    - 多个线程相互等待到达一个共同点
 *    - 当所有线程都到达后,同时继续执行
 *    - 提供分阶段同步的能力
 * 
 * 2. 可重用性:
 *    - 屏障突破后可以重复使用
 *    - 通过Generation机制区分不同的周期
 *    - 支持多次同步操作
 * 
 * 3. 回调机制:
 *    - 支持屏障突破时的回调操作
 *    - 回调在最后一个到达线程中执行
 *    - 提供屏障突破后的处理机会
 * 
 * 4. 状态管理:
 *    - 使用Generation标识不同的屏障周期
 *    - 通过broken标志管理屏障状态
 *    - 支持屏障的破坏和重置
 * 
 * 5. 线程安全:
 *    - 使用ReentrantLock保护临界区
 *    - 使用Condition实现线程等待和唤醒
 *    - 所有操作都是线程安全的
 * 
 * 6. 异常处理:
 *    - 支持线程中断处理
 *    - 支持超时处理
 *    - 支持回调异常处理
 *    - 提供详细的异常信息
 * 
 * 7. 灵活的等待机制:
 *    - 支持无限期等待
 *    - 支持可中断等待
 *    - 支持超时等待
 *    - 提供多种等待选项
 * 
 * 8. 高效的唤醒机制:
 *    - 屏障突破时一次性唤醒所有等待线程
 *    - 避免逐个唤醒的开销
 *    - 提高唤醒效率
 * 
 * 适用场景:
 * - 分阶段并行计算
 * - 多线程协同工作
 * - 需要同步点的场景
 * - 可重复使用的同步需求
 * - 需要回调处理的场景
 */

性能特征分析:

/**
 * CyclicBarrier的性能特征:
 * 
 * 时间复杂度:
 * - await(): O(1) 平均情况,O(∞) 最坏情况(等待时间)
 * - isBroken(): O(1)
 * - getNumberWaiting(): O(1)
 * - reset(): O(1)
 * - getParties(): O(1)
 * 
 * 空间复杂度:
 * - O(1) 基本存储空间
 * - O(n) 等待队列空间(n为等待线程数)
 * - 每个实例固定开销很小
 * 
 * 并发特性:
 * - 完全线程安全
 * - 支持高并发读写
 * - 无死锁风险
 * - 支持可重入性
 * 
 * 与CountDownLatch对比:
 * - CyclicBarrier > CountDownLatch(可重用性)
 * - CyclicBarrier > CountDownLatch(回调支持)
 * - CountDownLatch > CyclicBarrier(简单性)
 * - CountDownLatch > CyclicBarrier(性能)
 * 
 * 与ReentrantLock对比:
 * - CyclicBarrier > ReentrantLock(专门化)
 * - ReentrantLock > CyclicBarrier(灵活性)
 * - CyclicBarrier > ReentrantLock(易用性)
 * 
 * 内存使用:
 *    - 每个实例固定开销很小
 *    - 等待线程会增加内存使用
 *    - 及时GC,避免内存泄漏
 * 
 * 适用性:
 *    - 分阶段同步:性能优异
 *    - 简单等待:可能不如CountDownLatch
 *    - 复杂同步:性能优异
 *    - 需要重置:完美匹配
 * 
 * 性能优化:
 *    - 合理设置参与线程数量
 *    - 避免不必要的等待
 *    - 使用超时机制避免无限等待
 *    - 正确处理中断异常
 *    - 监控等待线程数量
 */

5. 使用示例和最佳实践

/**
 * 使用示例:
 * 
 * // 基本使用:分阶段并行计算
 * class MatrixMultiplier {
 *     private final int[][] matrixA;
 *     private final int[][] matrixB;
 *     private final int[][] result;
 *     private final int rows;
 *     private final int cols;
 *     
 *     public MatrixMultiplier(int[][] a, int[][] b) {
 *         this.matrixA = a;
 *         this.matrixB = b;
 *         this.rows = a.length;
 *         this.cols = b[0].length;
 *         this.result = new int[rows][cols];
 *     }
 *     
 *     public int[][] multiply() throws InterruptedException, BrokenBarrierException {
 *         int numThreads = Runtime.getRuntime().availableProcessors();
 *         CyclicBarrier barrier = new CyclicBarrier(numThreads, () -> {
 *             System.out.println("All threads completed phase");
 *         });
 *         
 *         Thread[] workers = new Thread[numThreads];
 *         int rowsPerThread = rows / numThreads;
 *         
 *         for (int i = 0; i < numThreads; i++) {
 *             final int startRow = i * rowsPerThread;
 *             final int endRow = (i == numThreads - 1) ? rows : (i + 1) * rowsPerThread;
 *             workers[i] = new Thread(new Worker(startRow, endRow, barrier));
 *             workers[i].start();
 *         }
 *         
 *         // 等待所有线程完成
 *         for (Thread worker : workers) {
 *             worker.join();
 *         }
 *         
 *         return result;
 *     }
 *     
 *     private class Worker implements Runnable {
 *         private final int startRow;
 *         private final int endRow;
 *         private final CyclicBarrier barrier;
 *         
 *         Worker(int startRow, int endRow, CyclicBarrier barrier) {
 *             this.startRow = startRow;
 *             this.endRow = endRow;
 *             this.barrier = barrier;
 *         }
 *         
 *         public void run() {
 *             try {
 *                 // 第一阶段:计算矩阵乘法的一部分
 *                 for (int i = startRow; i < endRow; i++) {
 *                     for (int j = 0; j < cols; j++) {
 *                         for (int k = 0; k < matrixB.length; k++) {
 *                             result[i][j] += matrixA[i][k] * matrixB[k][j];
 *                         }
 *                     }
 *                 }
 *                 
 *                 System.out.println("Thread " + Thread.currentThread().getName() + 
 *                                  " completed phase 1");
 *                 barrier.await(); // 第一阶段屏障
 *                 
 *                 // 第二阶段:验证计算结果
 *                 for (int i = startRow; i < endRow; i++) {
 *                     for (int j = 0; j < cols; j++) {
 *                         if (result[i][j] < 0) {
 *                             System.err.println("Negative result detected at [" + 
 *                                              i + "," + j + "]");
 *                         }
 *                     }
 *                 }
 *                 
 *                 System.out.println("Thread " + Thread.currentThread().getName() + 
 *                                  " completed phase 2");
 *                 barrier.await(); // 第二阶段屏障
 *                 
 *             } catch (InterruptedException | BrokenBarrierException e) {
 *                 Thread.currentThread().interrupt();
 *                 System.err.println("Worker thread interrupted: " + e.getMessage());
 *             }
 *         }
 *     }
 * }
 * 
 * // 带超时的使用示例
 * CyclicBarrier timeoutBarrier = new CyclicBarrier(3, () -> {
 *     System.out.println("All threads reached barrier");
 * });
 * 
 * for (int i = 0; i < 3; i++) {
 *     final int threadId = i;
 *     new Thread(() -> {
 *         try {
 *             System.out.println("Thread " + threadId + " started");
 *             Thread.sleep(1000); // 模拟工作
 *             System.out.println("Thread " + threadId + " waiting at barrier");
 *             
 *             // 带超时的等待
 *             if (timeoutBarrier.await(5, TimeUnit.SECONDS) == 0) {
 *                 System.out.println("Thread " + threadId + " was the last to arrive");
 *             } else {
 *                 System.out.println("Thread " + threadId + " arrived at barrier");
 *             }
 *         } catch (InterruptedException e) {
 *             System.out.println("Thread " + threadId + " interrupted");
 *             Thread.currentThread().interrupt();
 *         } catch (BrokenBarrierException e) {
 *             System.out.println("Thread " + threadId + " barrier broken: " + e.getMessage());
 *         } catch (TimeoutException e) {
 *             System.out.println("Thread " + threadId + " timed out at barrier");
 *             // 可以选择重置屏障
 *             timeoutBarrier.reset();
 *         }
 *     }).start();
 * }
 * 
 * // 多轮同步示例
 * class MultiRoundSynchronization {
 *     private final CyclicBarrier round1Barrier;
 *     private final CyclicBarrier round2Barrier;
 *     private final int numPlayers = 4;
 *     
 *     public MultiRoundSynchronization() {
 *         round1Barrier = new CyclicBarrier(numPlayers, () -> {
 *             System.out.println("=== Round 1 Complete ===");
 *         });
 *         round2Barrier = new CyclicBarrier(numPlayers, () -> {
 *             System.out.println("=== Round 2 Complete ===");
 *         });
 *     }
 *     
 *     public void playGame() {
 *         Thread[] players = new Thread[numPlayers];
 *         for (int i = 0; i < numPlayers; i++) {
 *             final int playerId = i;
 *             players[i] = new Thread(() -> {
 *                 try {
 *                     playRound1(playerId);
 *                     round1Barrier.await(); // 第一轮结束屏障
 *                     
 *                     playRound2(playerId);
 *                     round2Barrier.await(); // 第二轮结束屏障
 *                     
 *                     System.out.println("Player " + playerId + " finished game");
 *                 } catch (Exception e) {
 *                     System.err.println("Player " + playerId + " error: " + e.getMessage());
 *                     Thread.currentThread().interrupt();
 *                 }
 *             });
 *             players[i].start();
 *         }
 *         
 *         // 等待所有玩家完成
 *         for (Thread player : players) {
 *             try {
 *                 player.join();
 *             } catch (InterruptedException e) {
 *                 Thread.currentThread().interrupt();
 *             }
 *         }
 *     }
 *     
 *     private void playRound1(int playerId) {
 *         System.out.println("Player " + playerId + " playing round 1");
 *         try {
 *             Thread.sleep(1000 + playerId * 100); // 模拟不同时间的游戏
 *         } catch (InterruptedException e) {
 *             Thread.currentThread().interrupt();
 *         }
 *         System.out.println("Player " + playerId + " finished round 1");
 *     }
 *     
 *     private void playRound2(int playerId) {
 *         System.out.println("Player " + playerId + " playing round 2");
 *         try {
 *             Thread.sleep(1500 + playerId * 50); // 模拟不同时间的游戏
 *         } catch (InterruptedException e) {
 *             Thread.currentThread().interrupt();
 *         }
 *         System.out.println("Player " + playerId + " finished round 2");
 *     }
 * }
 * 
 * // 异常处理示例
 * class ExceptionHandlingExample {
 *     private final CyclicBarrier barrier = new CyclicBarrier(3, () -> {
 *         System.out.println("Barrier action executing...");
 *         // 模拟回调命令抛出异常
 *         if (Math.random() < 0.3) { // 30%概率抛出异常
 *             throw new RuntimeException("Barrier action failed");
 *         }
 *         System.out.println("Barrier action completed");
 *     });
 *     
 *     public void runWithErrorHandling() {
 *         for (int i = 0; i < 3; i++) {
 *             final int threadId = i;
 *             new Thread(() -> {
 *                 try {
 *                     System.out.println("Thread " + threadId + " working...");
 *                     Thread.sleep(1000);
 *                     System.out.println("Thread " + threadId + " waiting at barrier");
 *                     
 *                     int arrivalIndex = barrier.await();
 *                     System.out.println("Thread " + threadId + " passed barrier, " +
 *                                      "arrival index: " + arrivalIndex);
 *                 } catch (InterruptedException e) {
 *                     System.out.println("Thread " + threadId + " interrupted");
 *                     Thread.currentThread().interrupt();
 *                 } catch (BrokenBarrierException e) {
 *                     System.out.println("Thread " + threadId + " barrier broken: " + 
 *                                      e.getMessage());
 *                     // 可以选择重置屏障
 *                     if (!barrier.isBroken()) {
 *                         barrier.reset();
 *                     }
 *                 }
 *             }).start();
 *         }
 *     }
 * }
 * 
 * 最佳实践:
 * 
 * 1. 正确处理异常:
 *    CyclicBarrier barrier = new CyclicBarrier(3);
 *    
 *    // 正确的做法:处理所有可能的异常
 *    new Thread(() -> {
 *        try {
 *            // 执行任务
 *            performTask();
 *            
 *            // 等待屏障
 *            int arrivalIndex = barrier.await();
 *            System.out.println("Arrival index: " + arrivalIndex);
 *        } catch (InterruptedException e) {
 *            Thread.currentThread().interrupt(); // 恢复中断状态
 *            System.err.println("Thread interrupted: " + e.getMessage());
 *        } catch (BrokenBarrierException e) {
 *            System.err.println("Barrier broken: " + e.getMessage());
 *            // 可以选择重置屏障
 *            if (!barrier.isBroken()) {
 *                barrier.reset();
 *            }
 *        }
 *    }).start();
 *    
 *    // 错误的做法:忽略异常
 *    // new Thread(() -> {
 *    //     barrier.await(); // 没有处理异常
 *    // }).start();
 * 
 * 2. 合理使用回调命令:
 *    CyclicBarrier barrier = new CyclicBarrier(4, () -> {
 *        // 在回调命令中执行轻量级操作
 *        System.out.println("All threads reached barrier at: " + 
 *                         new Date(System.currentTimeMillis()));
 *        
 *        // 避免在回调命令中执行耗时操作
 *        // 避免在回调命令中抛出异常(会影响所有等待线程)
 *    });
 *    
 *    // 错误的做法:在回调命令中执行耗时操作
 *    // CyclicBarrier badBarrier = new CyclicBarrier(4, () -> {
 *    //     Thread.sleep(5000); // 耗时操作会阻塞所有线程
 *    // });
 * 
 * 3. 使用超时机制:
 *    CyclicBarrier barrier = new CyclicBarrier(3);
 *    
 *    // 使用超时避免无限等待
 *    new Thread(() -> {
 *        try {
 *            if (barrier.await(10, TimeUnit.SECONDS) == 0) {
 *                System.out.println("Last thread to arrive");
 *            } else {
 *                System.out.println("Arrived at barrier");
 *            }
 *        } catch (InterruptedException e) {
 *            Thread.currentThread().interrupt();
 *        } catch (BrokenBarrierException e) {
 *            System.err.println("Barrier broken: " + e.getMessage());
 *        } catch (TimeoutException e) {
 *            System.err.println("Timed out waiting for barrier");
 *            // 处理超时情况
 *            barrier.reset(); // 重置屏障
 *        }
 *    }).start();
 * 
 * 4. 正确设置参与线程数量:
 *    // 根据实际需求设置parties
 *    int actualThreadCount = calculateActualThreadCount();
 *    CyclicBarrier barrier = new CyclicBarrier(actualThreadCount);
 *    
 *    // 错误的做法:硬编码parties值
 *    // CyclicBarrier wrongBarrier = new CyclicBarrier(10); // 可能与实际线程数不符
 * 
 * 5. 避免死锁:
 *    CyclicBarrier barrier1 = new CyclicBarrier(2);
 *    CyclicBarrier barrier2 = new CyclicBarrier(2);
 *    
 *    // 错误的做法:可能导致死锁
 *    // Thread t1 = new Thread(() -> {
 *    //     try {
 *    //         barrier1.await();
 *    //         barrier2.await(); // 可能与另一个线程形成死锁
 *    //     } catch (Exception e) { /* 处理异常 */ }
 *    // });
 *    // 
 *    // Thread t2 = new Thread(() -> {
 *    //     try {
 *    //         barrier2.await(); // 可能与另一个线程形成死锁
 *    //         barrier1.await();
 *    //     } catch (Exception e) { /* 处理异常 */ }
 *    // });
 *    
 *    // 正确的做法:保持一致的屏障获取顺序
 *    Thread t1 = new Thread(() -> {
 *        try {
 *            barrier1.await();
 *            barrier2.await();
 *        } catch (Exception e) { /* 处理异常 */ }
 *    });
 *    
 *    Thread t2 = new Thread(() -> {
 *        try {
 *            barrier1.await(); // 保持相同的获取顺序
 *            barrier2.await();
 *        } catch (Exception e) { /* 处理异常 */ }
 *    });
 * 
 * 6. 监控屏障状态:
 *    CyclicBarrier barrier = new CyclicBarrier(5);
 *    
 *    // 定期检查屏障状态
 *    public void monitorBarrier() {
 *        System.out.println("Parties: " + barrier.getParties());
 *        System.out.println("Waiting: " + barrier.getNumberWaiting());
 *        System.out.println("Broken: " + barrier.isBroken());
 *    }
 *    
 *    // 在高负载时监控性能
 *    public void performanceMonitoring() {
 *        long startTime = System.nanoTime();
 *        try {
 *            barrier.await();
 *        } catch (Exception e) {
 *            Thread.currentThread().interrupt();
 *        }
 *        long endTime = System.nanoTime();
 *        System.out.println("Barrier wait time: " + (endTime - startTime) + " ns");
 *    }
 * 
 * 7. 合理使用reset()方法:
 *    CyclicBarrier barrier = new CyclicBarrier(3);
 *    
 *    // 在异常情况下重置屏障
 *    public void handleException() {
 *        if (barrier.isBroken()) {
 *            System.out.println("Barrier is broken, resetting...");
 *            barrier.reset();
 *            System.out.println("Barrier reset completed");
 *        }
 *    }
 *    
 *    // 避免频繁重置
 *    // barrier.reset(); // 不必要的重置会影响性能
 * 
 * 8. 正确处理线程中断:
 *    CyclicBarrier barrier = new CyclicBarrier(3);
 *    
 *    Thread worker = new Thread(() -> {
 *        try {
 *            // 执行任务
 *            performTask();
 *            
 *            // 等待屏障
 *            barrier.await();
 *            System.out.println("Task completed successfully");
 *        } catch (InterruptedException e) {
 *            System.out.println("Task interrupted");
 *            Thread.currentThread().interrupt(); // 恢复中断状态
 *        } catch (BrokenBarrierException e) {
 *            System.err.println("Barrier broken due to interruption");
 *        }
 *    });
 *    
 *    worker.start();
 *    
 *    // 在适当时候中断线程
 *    // worker.interrupt(); // 可以优雅地中止任务
 * 
 * 9. 使用多个屏障实现复杂同步:
 *    class ComplexSynchronization {
 *        private final CyclicBarrier phase1Barrier;
 *        private final CyclicBarrier phase2Barrier;
 *        private final CyclicBarrier completionBarrier;
 *        
 *        public ComplexSynchronization(int threadCount) {
 *            phase1Barrier = new CyclicBarrier(threadCount, () -> {
 *                System.out.println("Phase 1 completed");
 *            });
 *            phase2Barrier = new CyclicBarrier(threadCount, () -> {
 *                System.out.println("Phase 2 completed");
 *            });
 *            completionBarrier = new CyclicBarrier(threadCount, () -> {
 *                System.out.println("All phases completed");
 *            });
 *        }
 *        
 *        public void executeComplexTask() {
 *            // 执行多阶段任务
 *            try {
 *                performPhase1();
 *                phase1Barrier.await(); // 第一阶段同步点
 *                
 *                performPhase2();
 *                phase2Barrier.await(); // 第二阶段同步点
 *                
 *                performCleanup();
 *                completionBarrier.await(); // 完成同步点
 *            } catch (Exception e) {
 *                Thread.currentThread().interrupt();
 *            }
 *        }
 *    }
 * 
 * 10. 性能调优:
 *    // 在高并发场景下优化性能
 *    CyclicBarrier barrier = new CyclicBarrier(
 *        Runtime.getRuntime().availableProcessors(),
 *        () -> {
 *            // 轻量级的回调操作
 *            System.out.println("Synchronization point reached");
 *        }
 *    );
 *    
 *    // 避免在回调中执行耗时操作
 *    // 使用异步处理复杂逻辑
 *    public void asyncCallbackProcessing() {
 *        CyclicBarrier barrier = new CyclicBarrier(4, () -> {
 *            // 立即返回,异步处理复杂逻辑
 *            CompletableFuture.runAsync(() -> {
 *                // 复杂的后处理逻辑
 *                performComplexPostProcessing();
 *            });
 *        });
 *    }
 */

6. 与其他同步机制的比较

/**
 * CyclicBarrier vs CountDownLatch vs Semaphore vs Phaser:
 * 
 * CyclicBarrier:
 * - 多线程相互等待到达同步点
 * - 可重复使用
 * - 支持回调命令
 * - 适用于分阶段同步
 * - 可重入性支持
 * 
 * CountDownLatch:
 * - 一次性使用,计数器只能减少
 * - 一个或多个线程等待其他线程完成
 * - 不支持重置
 * - 适用于简单的等待/通知场景
 * - 性能较好
 * 
 * Semaphore:
 * - 控制资源访问数量
 * - 支持许可证的获取和释放
 * - 可以动态调整许可数量
 * - 适用于资源池管理
 * - 支持公平性和非公平性
 * 
 * Phaser:
 * - JDK 7新增,功能最强大
 * - 支持动态注册和注销参与者
 * - 支持分层组织
 * - 可重复使用
 * - 适用于复杂的同步场景
 * 
 * 性能对比:
 * - 简单等待:CountDownLatch > CyclicBarrier > Semaphore > Phaser
 * - 复杂同步:Phaser > CyclicBarrier > Semaphore > CountDownLatch
 * - 内存使用:CountDownLatch < CyclicBarrier < Semaphore < Phaser
 * - 功能丰富度:Phaser > CyclicBarrier > Semaphore > CountDownLatch
 * 
 * 选择建议:
 * - 简单等待多个事件完成:CountDownLatch
 * - 分阶段并行计算:CyclicBarrier
 * - 资源访问控制:Semaphore
 * - 复杂同步需求:Phaser
 * - 需要重置功能:CyclicBarrier或Phaser
 * - 高性能简单场景:CountDownLatch
 * 
 * 使用场景:
 * - CyclicBarrier:分阶段并行计算、多线程协同工作
 * - CountDownLatch:主线程等待子线程完成、启动门闩、关闭门闩
 * - Semaphore:资源池、流量控制、连接池
 * - Phaser:复杂的工作流、动态参与者管理
 * 
 * 线程安全性:
 * - 所有机制都提供完全的线程安全性
 * - CyclicBarrier和Phaser支持更复杂的同步模式
 * - CountDownLatch和Semaphore适用于简单的同步需求
 * 
 * 可重用性:
 * - CyclicBarrier:完全可重用
 * - Phaser:完全可重用
 * - CountDownLatch:一次性使用
 * - Semaphore:可重用(通过acquire/release)
 */

7. 总结

CyclicBarrier 的核心特性:

  1. 屏障同步

    • 多个线程相互等待到达同步点
    • 当所有线程都到达后,同时继续执行
    • 提供分阶段同步的能力
  2. 可重用性

    • 屏障突破后可以重复使用
    • 通过Generation机制区分不同的周期
    • 支持多次同步操作
  3. 回调机制

    • 支持屏障突破时的回调操作
    • 回调在最后一个到达线程中执行
    • 提供屏障突破后的处理机会
  4. 状态管理

    • 使用Generation标识不同的屏障周期
    • 通过broken标志管理屏障状态
    • 支持屏障的破坏和重置
  5. 线程安全

    • 使用ReentrantLock保护临界区
    • 使用Condition实现线程等待和唤醒
    • 所有操作都是线程安全的
  6. 异常处理

    • 支持线程中断处理
    • 支持超时处理
    • 支持回调异常处理
    • 提供详细的异常信息
  7. 灵活的等待机制

    • 支持无限期等待
    • 支持可中断等待
    • 支持超时等待
    • 提供多种等待选项
  8. 高效的唤醒机制

    • 屏障突破时一次性唤醒所有等待线程
    • 避免逐个唤醒的开销
    • 提高唤醒效率

适用场景:

  • 分阶段并行计算
  • 多线程协同工作
  • 需要同步点的场景
  • 可重复使用的同步需求
  • 需要回调处理的场景
  • 复杂的多阶段同步
  • 需要监控和诊断的场景

注意事项:

  • 必须正确处理所有可能的异常
  • 避免在回调命令中执行耗时操作
  • 合理使用超时机制避免无限等待
  • 正确处理线程中断
  • 避免死锁(保持屏障获取顺序)
  • 监控屏障状态和性能
  • 合理设置参与线程数量
  • 正确使用reset()方法

性能优化建议:

  1. 根据实际需求设置合适的参与线程数量
  2. 使用超时机制避免无限等待
  3. 在回调命令中执行轻量级操作
  4. 正确处理中断和异常
  5. 监控屏障的使用情况
  6. 避免不必要的屏障重置
  7. 保持一致的屏障获取顺序
  8. 在高并发场景下优化性能
  9. 使用异步处理复杂回调逻辑
  10. 定期分析和调优同步性能
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值