编写一个示例程序,展示如何使用 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();
}
}
}
程序说明
CyclicBarrier
的创建:
- new CyclicBarrier(5, Runnable action):
- 参数
5
指定有 5 个线程需要到达同步点。 - 第二个参数是回调动作,当所有线程都到达屏障时,自动执行。
- 参数
barrier.await()
的作用:
- 每个线程执行到屏障后会调用
await()
,然后阻塞,直到所有线程都调用了await()
。 - 当最后一个线程调用
await()
时,屏障打开,所有线程继续执行。
- 任务模拟:
- 线程模拟不同的运动员,它们完成任务的时间不一致(通过
Thread.sleep
模拟随机时间)。 - 当所有运动员到达终点后,裁判宣布结果。
- 回调任务:
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!
适用场景
- 多线程的阶段性任务同步:
- 适用于分阶段任务的场景,例如多个线程在完成第一阶段后再统一进入第二阶段。
- 并发任务的协调:
- 如跑步比赛、分布式任务的汇总、数据处理任务的阶段性同步。
- 循环使用:
CyclicBarrier
可以被重复使用,适合需要多次同步的场景。
扩展:CyclicBarrier 的常见方法
await()
:- 阻塞当前线程,直到所有线程到达屏障。
- 如果屏障被中断或重置,会抛出
BrokenBarrierException
。
reset()
:- 重置屏障,唤醒所有等待的线程,并让屏障重新可用。
getNumberWaiting()
:- 返回当前等待屏障的线程数量。
isBroken()
:- 检查屏障是否被中断。
总结
CyclicBarrier
的核心功能:- 用于多线程的同步,当所有线程都到达屏障时,再统一执行。
- 提供了回调功能,方便实现额外的任务。
- 应用场景:
- 阶段性任务同步(如任务分组执行)。
- 并发任务的协调(如多人协作或比赛)。