ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
`CyclicBarrier` 是 Java 的并发工具类,允许一组线程相互等待,直到所有线程都到达某个公共屏障点。当所有参与线程都调用 `await()` 方法到达屏障点时,它们才能继续执行。`CyclicBarrier` 在多线程编程中非常有用,特别是在需要协调线程的执行顺序时。 ### 实际使用场景 #### 1\. **多阶段任务协调** 在许多应用场景中,任务可以被分解为多个阶段,每个阶段都需要多个线程的协作。例如,在一个并行计算的程序中,不同线程可能需要在某个计算阶段完成后才能开始下一阶段。`CyclicBarrier` 可以用于确保所有线程都完成当前阶段的工作后再进入下一阶段。 **示例代码:** ~~~ java复制代码import java.util.concurrent.CyclicBarrier; public class CyclicBarrierExample { private static final int THREAD_COUNT = 3; public static void main(String[] args) { // 创建一个 CyclicBarrier,用于等待 3 个线程 CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT, () -> { // 当所有线程都到达屏障点时,执行的操作 System.out.println("All threads have reached the barrier. Moving to the next phase."); }); // 启动 3 个线程,每个线程都在某个阶段等待屏障 for (int i = 0; i < THREAD_COUNT; i++) { new Thread(new Task(barrier)).start(); } } static class Task implements Runnable { private final CyclicBarrier barrier; public Task(CyclicBarrier barrier) { this.barrier = barrier; } @Override public void run() { try { // 模拟某个阶段的任务 System.out.println(Thread.currentThread().getName() + " is performing task."); Thread.sleep((int) (Math.random() * 1000)); // 到达屏障点,等待其他线程 System.out.println(Thread.currentThread().getName() + " reached the barrier."); barrier.await(); // 等待所有线程到达屏障点 // 所有线程都到达后,执行的操作 System.out.println(Thread.currentThread().getName() + " continues after barrier."); } catch (Exception e) { e.printStackTrace(); } } } } ~~~ 在这个示例中,`CyclicBarrier` 用于协调三个线程,确保它们在执行完某个阶段的任务后都到达屏障点,然后再继续执行下一阶段。 #### 2\. **并行数据处理** 在并行数据处理场景中,`CyclicBarrier` 可以用来分阶段处理数据。例如,在将数据分成多个部分并在多个线程中处理后,需要在所有线程完成数据处理之前进行某些操作(如汇总或结果处理)。 **示例代码:** ~~~ java复制代码import java.util.concurrent.CyclicBarrier; import java.util.concurrent.BrokenBarrierException; public class ParallelDataProcessing { private static final int THREAD_COUNT = 4; public static void main(String[] args) { CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT, () -> { System.out.println("All threads completed data processing phase."); }); // 启动多个线程进行数据处理 for (int i = 0; i < THREAD_COUNT; i++) { new Thread(new DataProcessingTask(barrier)).start(); } } static class DataProcessingTask implements Runnable { private final CyclicBarrier barrier; public DataProcessingTask(CyclicBarrier barrier) { this.barrier = barrier; } @Override public void run() { try { // 处理数据 System.out.println(Thread.currentThread().getName() + " is processing data."); Thread.sleep((int) (Math.random() * 1000)); // 到达屏障点,等待其他线程 barrier.await(); // 等待所有线程完成数据处理 // 所有线程都完成后执行的操作 System.out.println(Thread.currentThread().getName() + " continues with post-processing."); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } } } ~~~ 在这个示例中,`CyclicBarrier` 用于协调多个线程的数据处理任务,确保所有线程完成数据处理后再进行后续操作。 #### 3\. **游戏中的同步** 在某些多人游戏中,可能需要确保所有玩家在某个游戏阶段完成某项任务后,才能开始下一阶段的任务。`CyclicBarrier` 可以用于这种场景,确保所有玩家都完成当前任务后才开始下一阶段。 **示例代码:** ~~~ java复制代码import java.util.concurrent.CyclicBarrier; public class GameSynchronization { private static final int PLAYER_COUNT = 4; public static void main(String[] args) { CyclicBarrier barrier = new CyclicBarrier(PLAYER_COUNT, () -> { System.out.println("All players are ready. Starting the next round."); }); // 启动多个线程模拟玩家 for (int i = 0; i < PLAYER_COUNT; i++) { new Thread(new Player(barrier)).start(); } } static class Player implements Runnable { private final CyclicBarrier barrier; public Player(CyclicBarrier barrier) { this.barrier = barrier; } @Override public void run() { try { // 模拟玩家准备阶段 System.out.println(Thread.currentThread().getName() + " is getting ready."); Thread.sleep((int) (Math.random() * 1000)); // 到达屏障点,等待其他玩家 System.out.println(Thread.currentThread().getName() + " is waiting at the barrier."); barrier.await(); // 等待所有玩家准备好 // 所有玩家都准备好后执行的操作 System.out.println(Thread.currentThread().getName() + " continues to play."); } catch (Exception e) { e.printStackTrace(); } } } } ~~~ 在这个示例中,`CyclicBarrier` 用于同步游戏中的多个玩家,确保所有玩家在每个游戏回合开始前都准备好。 ### 总结 `CyclicBarrier` 是一种非常有用的并发工具类,用于协调一组线程,确保它们在到达某个屏障点之前保持同步。它的主要应用场景包括多阶段任务协调、并行数据处理和游戏中的同步等。在这些场景中,`CyclicBarrier` 可以确保线程按照预期的顺序进行操作,提高程序的稳定性和一致性。