编写一个示例程序,展示如何使用 CyclicBarrier 类进行多线程同步和协作

示例程序:使用 CyclicBarrier 实现多线程同步与协作**

以下程序演示了如何使用 CyclicBarrier 在多线程中实现任务同步。例如,多个线程模拟运动员在跑步比赛中,只有当所有人到达终点后,裁判才宣布比赛结束。


代码实现

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierExample {

    public static void main(String[] args) {
        // 定义一个 CyclicBarrier,等待 5 个线程到达后执行
        CyclicBarrier barrier = new CyclicBarrier(5, () -> {
            System.out.println("All participants have finished. Judge announces the result!");
        });

        // 创建并启动 5 个线程
        for (int i = 1; i <= 5; i++) {
            new Thread(new Participant(barrier, "Runner-" + i)).start();
        }
    }
}

// 模拟参与者的任务
class Participant implements Runnable {
    private final CyclicBarrier barrier;
    private final String name;

    public Participant(CyclicBarrier barrier, String name) {
        this.barrier = barrier;
        this.name = name;
    }

    @Override
    public void run() {
        try {
            System.out.println(name + " is running...");
            // 模拟任务执行时间
            Thread.sleep((long) (Math.random() * 3000));

            System.out.println(name + " reached the finish line.");
            // 等待其他线程
            barrier.await();
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

程序说明

  1. CyclicBarrier 的创建
  • new CyclicBarrier(5, Runnable action):
    • 参数 5 指定有 5 个线程需要到达同步点。
    • 第二个参数是回调动作,当所有线程都到达屏障时,自动执行。
  1. barrier.await() 的作用
  • 每个线程执行到屏障后会调用 await(),然后阻塞,直到所有线程都调用了 await()
  • 当最后一个线程调用 await() 时,屏障打开,所有线程继续执行。
  1. 任务模拟
  • 线程模拟不同的运动员,它们完成任务的时间不一致(通过 Thread.sleep 模拟随机时间)。
  • 当所有运动员到达终点后,裁判宣布结果。
  1. 回调任务
  • CyclicBarrier 的回调任务(裁判宣布结果)在屏障打开时由最后一个到达的线程执行。

示例输出

运行示例代码后,输出可能如下:

Runner-1 is running...
Runner-2 is running...
Runner-3 is running...
Runner-4 is running...
Runner-5 is running...
Runner-3 reached the finish line.
Runner-5 reached the finish line.
Runner-1 reached the finish line.
Runner-4 reached the finish line.
Runner-2 reached the finish line.
All participants have finished. Judge announces the result!

适用场景

  1. 多线程的阶段性任务同步
    • 适用于分阶段任务的场景,例如多个线程在完成第一阶段后再统一进入第二阶段。
  2. 并发任务的协调
    • 如跑步比赛、分布式任务的汇总、数据处理任务的阶段性同步。
  3. 循环使用
    • CyclicBarrier 可以被重复使用,适合需要多次同步的场景。

扩展:CyclicBarrier 的常见方法

  1. await()
    • 阻塞当前线程,直到所有线程到达屏障。
    • 如果屏障被中断或重置,会抛出 BrokenBarrierException
  2. reset()
    • 重置屏障,唤醒所有等待的线程,并让屏障重新可用。
  3. getNumberWaiting()
    • 返回当前等待屏障的线程数量。
  4. isBroken()
    • 检查屏障是否被中断。

总结

  • CyclicBarrier 的核心功能
    • 用于多线程的同步,当所有线程都到达屏障时,再统一执行。
    • 提供了回调功能,方便实现额外的任务。
  • 应用场景
    • 阶段性任务同步(如任务分组执行)。
    • 并发任务的协调(如多人协作或比赛)。

发表评论

后才能评论