当前位置: 首页 > news >正文

CyclicBarrier(同步屏障)是什么?它的原理和用法是什么?

CyclicBarrier 是 Java 并发包(java.util.concurrent)中的一种同步工具,用于让一组线程互相等待,直到所有线程都到达某个公共屏障点(barrier point)后,再继续执行后续任务。其名称中的 “Cyclic”(循环)表明它可以被重复使用。


核心原理

  1. 计数器机制

    • 初始化时设置一个参与线程数 N(屏障的阈值)。
    • 每个线程调用 await() 时,计数器减 1,并进入等待状态。
    • 当第 N 个线程调用 await() 后,计数器归零,所有等待线程被唤醒,继续执行。
  2. 可选的屏障动作

    • 构造时可传入一个 Runnable 任务(称为屏障动作)。
    • 当所有线程到达屏障时,由最后一个到达的线程执行此任务(其他线程仍处于唤醒过程中)。
  3. 循环重置

    • 当线程被释放后,计数器自动重置为初始值 N,可立即用于下一轮同步(区别于一次性工具 CountDownLatch)。
  4. 异常处理

    • 若等待中线程被中断或超时,会抛出 BrokenBarrierException,屏障状态变为“损坏”,需调用 reset() 重置。

核心方法

方法说明
CyclicBarrier(int parties)创建屏障,指定参与线程数
CyclicBarrier(int parties, Runnable barrierAction)创建屏障,并指定屏障触发时的回调任务
int await()等待所有线程到达屏障(可中断)
int await(long timeout, TimeUnit unit)带超时的等待
void reset()强制重置屏障(等待中的线程会抛出异常)
int getParties()获取参与线程数
boolean isBroken()检查屏障是否损坏

使用场景

  • 多阶段任务:将大任务拆分为多个阶段,每个阶段需所有子任务完成后才能进入下一阶段。
  • 并行计算:多个线程计算不同部分,最终合并结果。
  • 模拟测试:模拟高并发场景(如压力测试中等待所有线程就绪后同时发起请求)。

代码示例

import java.util.concurrent.*;public class CyclicBarrierDemo {public static void main(String[] args) {final int THREAD_COUNT = 3;// 创建屏障,并设置屏障触发时的回调任务CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT, () -> System.out.println("【屏障触发】所有线程已就位,执行合并任务!"));for (int i = 0; i < THREAD_COUNT; i++) {new Thread(() -> {try {System.out.println(Thread.currentThread().getName() + " 开始执行子任务...");Thread.sleep((long) (Math.random() * 2000)); // 模拟任务耗时System.out.println(Thread.currentThread().getName() + " 子任务完成,等待其他线程");// 等待其他线程到达屏障barrier.await();System.out.println(Thread.currentThread().getName() + " 继续后续操作");} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}, "线程-" + i).start();}}
}
输出可能结果
线程-0 开始执行子任务...
线程-1 开始执行子任务...
线程-2 开始执行子任务...
线程-0 子任务完成,等待其他线程
线程-2 子任务完成,等待其他线程
线程-1 子任务完成,等待其他线程
【屏障触发】所有线程已就位,执行合并任务!
线程-1 继续后续操作
线程-0 继续后续操作
线程-2 继续后续操作

注意事项

  1. 异常处理

    • 若线程在 await() 时被中断,会抛出 InterruptedException
    • 若屏障在等待期间被重置或损坏,会抛出 BrokenBarrierException
  2. 屏障重置

    • 调用 reset() 会强制重置屏障,但正在等待的线程会立即抛出异常
    • 屏障正常触发后会自动重置,无需手动操作。
  3. 性能影响

    • 大量线程频繁等待可能成为性能瓶颈,需合理设计线程数量。

与 CountDownLatch 的区别

特性CyclicBarrierCountDownLatch
重用性✅ 可循环使用❌ 一次性
计数器自动重置手动重置(需重新创建实例)
核心动作线程互相等待线程等待外部事件(计数器归零)
任务触发支持屏障动作(回调)无内置回调机制
适用场景多阶段并行任务启动准备、结束通知等一次性场景

简单类比:

  • CountDownLatch:裁判发令枪(等待所有运动员就位后开枪)。
  • CyclicBarrier:团队集合点(所有成员到齐后继续下一步行动)。

通过合理使用 CyclicBarrier,可以高效解决多线程分阶段协作问题,提升程序的并行性和健壮性。

你想要的技术资料我全都有

在这里插入图片描述

http://www.dtcms.com/a/263645.html

相关文章:

  • 新手向:从零开始Node.js超详细安装、配置与使用指南
  • Embeddings模型
  • 微服务介绍
  • Unity进阶课程【六】Android、ios、Pad 终端设备打包局域网IP调试、USB调试、性能检测、控制台打印日志等、C#
  • 【RTSP从零实践】4、使用RTP协议封装并传输AAC
  • 学习threejs,使用自定义GLSL 着色器,生成艺术作品
  • 电机参数测量
  • 自由学习记录(66)
  • JT808教程:消息的结构
  • react中在Antd3.x版本中 Select框在单选时 选中框的高度调整
  • Qt 实现Opencv功能模块切换界面功能
  • 【算法】动态规划:python实现 1
  • TensorFlow内核剖析:分布式TensorFlow架构解析与实战指南
  • mini-electron使用方法
  • 内部类与Lambda的衍生关系(了解学习内部类,Lambda一篇即可)
  • C# WPF + Helix Toolkit 实战:用两种方式打造“六面异色立方体”
  • QNN SDK学习笔记
  • 二十八、【环境管理篇】灵活应对:多测试环境配置与切换
  • python开发|yaml用法知识介绍
  • STM32F4操作内部FLASH简洁版
  • 【代码审计】安全审核常见漏洞修复策略
  • 位运算经典题解
  • 启用不安全的HTTP方法
  • 图像处理专业书籍以及网络资源总结
  • Java编程之状态模式
  • 《UE5_C++多人TPS完整教程》学习笔记40 ——《P41 装备(武器)姿势(Equipped Pose)》
  • 基于Socketserver+ThreadPoolExecutor+Thread构造的TCP网络实时通信程序
  • mac重复文件清理,摄影师同款清理方案
  • flv.js视频/直播流测试demo
  • 2025 推理技术风向标:DeepSeek-R1 揭示大模型从 “记忆” 到 “思考” 的进化路径