CyclicBarrier是Java并发包中一个非常有用的同步工具类,属于java.util.concurrent包。它允许一组线程互相等待,直到所有线程都到达一个公共的屏障点。CyclicBarrier在并发编程中常用于需要多个线程共同完成某个工作时的场景。

CyclicBarrier的基本原理

CyclicBarrier的构造函数需要指明需要等待的线程数量。例如,如果设置为5,则只有当5个线程都调用了await方法,才会继续执行后面的代码。当所有线程都到达屏障点以后,CyclicBarrier会被重置,可以再次使用,这也是CyclicBarrier与其他同步工具的一个不同点。

CyclicBarrier的工作原理可以简单总结为: 1. 每个线程在执行到达屏障的方法时,都会在CyclicBarrier内部进行计数。 2. 当计数达到预设值时,所有等待的线程被唤醒,继续执行。 3. 如果某个线程在等待过程中中断,CyclicBarrier会抛出BrokenBarrierException异常,其他线程也会被阻塞。

CyclicBarrier的源码解析

CyclicBarrier的核心类由多个内部类组成,其中最重要的字段是countparties。其中count用于记录当前到达屏障的线程数量,而parties则表示需要等待的线程总数。

CyclicBarrier的关键方法如下:

  • await():调用该方法的线程会被阻塞直到count达到parties
  • reset():重置CyclicBarrier的状态,允许其重新使用。
  • getParties():获取设置的等待线程数量。

以下是CyclicBarrier的部分简化源码(主要结构):

public class CyclicBarrier {
    private final int parties; // 等待的线程数量
    private int count; // 当前到达的线程数量

    public CyclicBarrier(int parties) {
        if (parties <= 0) throw new IllegalArgumentException();
        this.parties = parties;
        this.count = parties; // 初始化计数
    }

    public synchronized int await() throws InterruptedException, BrokenBarrierException {
        // 增加到达计数
        count--;
        if (count == 0) {
            count = parties; // 重置计数
            notifyAll(); // 唤醒所有等待线程
            return 0; // 返回结果
        }
        // 等待其他线程的到达
        while (count > 0) {
            wait();
        }
        return 0;
    }
}

CyclicBarrier的示例

下面是一个使用CyclicBarrier的简单示例,我们将使用4个线程并行任务,所有线程在一个点上等待,直到都准备好再一起执行某个操作。

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierExample {
    private static final int NUMBER_OF_THREADS = 4;

    public static void main(String[] args) {
        // 创建一个CyclicBarrier对象,设定等待4个线程
        CyclicBarrier barrier = new CyclicBarrier(NUMBER_OF_THREADS, new Runnable() {
            public void run() {
                System.out.println("所有线程已经到达,开始执行主操作...");
            }
        });

        for (int i = 0; i < NUMBER_OF_THREADS; i++) {
            final int threadNumber = i;
            new Thread(() -> {
                try {
                    System.out.println("线程 " + threadNumber + " 正在准备...");
                    // 模拟一些准备工作
                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("线程 " + threadNumber + " 准备好了,等待其他线程...");
                    barrier.await(); // 等待其他线程到达
                    System.out.println("线程 " + threadNumber + " 开始执行!");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

总结

CyclicBarrier在多线程编程中扮演着重要角色,可以提高程序的效率和可读性。它使得多个线程能够在同一时刻执行某项操作,尤其适合需要协作的任务。通过以上的源码解析和示例代码,相信您对CyclicBarrier有了更深入的理解。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部