news 2026/5/9 17:09:57

Java并发利器:CyclicBarrier深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java并发利器:CyclicBarrier深度解析

CyclicBarrier是 Java 并发包中一个可重用的同步辅助工具,用于让一组固定数量的线程互相等待,直到所有线程都到达某个“屏障点”(barrier point),然后一起继续执行。它的名字中的“Cyclic”(循环)正是因为它可以在一次使用后重置并重复使用

下面从核心思想、内部机制、关键特性、与 CountDownLatch 的区别、内存语义五个方面帮你彻底理解。


一、核心思想:多线程“齐步走”

想象一个班级做操:

  • 老师喊:“所有人到操场集合!”
  • 学生 A、B、C……陆续到达,但必须等最后一个同学到齐,才能开始做操。
  • 做完一轮后,老师又喊:“再来一轮!”,大家再次集合 →这就是“循环”

在程序中:

  • 每个线程执行一部分工作;
  • 然后调用barrier.await()等待;
  • 所有 N 个线程都调用了await(),屏障“放行”,所有线程继续;
  • 下次还能再用同一个CyclicBarrier

典型场景:并行迭代计算(如 Jacobi 迭代)、多阶段任务同步。


二、内部实现机制

1. 核心组件

privatefinalReentrantLocklock=newReentrantLock();privatefinalConditiontrip=lock.newCondition();// 等待/唤醒的条件privatefinalintparties;// 总线程数(固定)privateintcount;// 当前轮次剩余未到达的线程数privateGenerationgeneration;// 表示当前“代”(一轮)privatefinalRunnablebarrierCommand;// 屏障动作(可选)

2.Generation:区分“轮次”

  • 每次屏障触发(tripped)或重置(reset),就创建一个新的Generation对象。
  • 所有等待的线程都关联到同一个 generation
  • 如果某轮被中断(如超时、异常),该 generation 被标记为broken = true
  • 新一轮开始时,generation指向新对象,旧的被废弃。

💡 作用:防止“跨轮次”的线程互相干扰(比如上一轮的线程误唤醒下一轮的)。

3.dowait():核心等待逻辑

intindex=--count;// 倒计数if(index==0){// 最后一个线程到达!执行 barrierCommand(如果有);nextGeneration();// 重置 count,新建 generation,signalAll()}else{// 不是最后一个,进入等待trip.await();// 或 awaitNanos()}
关键行为:
  • 最后一个到达的线程负责:
    • 执行barrierCommand(如合并结果);
    • 调用trip.signalAll()唤醒所有等待者;
    • 创建新一代(nextGeneration())。
  • 其他线程:阻塞在trip.await(),直到被唤醒。

三、关键特性

1.All-or-Nothing(全有或全无)

  • 如果任何一个线程在等待时被中断、超时、或调用reset()
  • 那么所有等待的线程都会抛出BrokenBarrierException
  • 并且 barrier 进入broken 状态

这保证了“要么全部通过,要么全部失败”,避免部分线程卡住。

2.Barrier Action(屏障动作)

  • 可在构造时传入一个Runnable
    newCyclicBarrier(N,()->mergeResults());
  • 该动作由最后一个到达的线程执行,在唤醒其他人之前
  • 常用于:汇总本轮结果、更新全局状态。

3.返回到达序号

intarrivalIndex=barrier.await();
  • 返回值:parties - 1表示第一个到达,0表示最后一个。
  • 可用于:指定某个线程(如if (await() == 0))执行日志、清理等操作。

4.可重置(reset)

barrier.reset();// 立即打破当前轮次,开启新轮次
  • 所有当前等待的线程会收到BrokenBarrierException
  • 之后可以重新开始新一轮同步。

四、与CountDownLatch的本质区别

特性CyclicBarrierCountDownLatch
用途多线程互相等待(N 对 N)一个/多个线程等其他线程完成(1 对 N 或 N 对 1)
可重用✅ 是(cyclic)❌ 否(one-shot)
触发者所有参与线程自己调用await()其他线程调用countDown()
屏障动作✅ 支持(最后一个线程执行)❌ 不支持
失败模型All-or-nothing(全失败)单独失败不影响他人
底层实现ReentrantLock + ConditionAQS 共享模式

📌简单记

  • CountDownLatch“我等你们干完”(协调者模式)。
  • CyclicBarrier“我们互相等,一起走”(协作模式)。

五、内存可见性(Memory Consistency)

Java 内存模型保证以下happens-before关系:

线程 A 在await()之前的操作
happens-before
屏障动作(barrier action)的执行
happens-before
其他线程从await()返回后的操作

这意味着:

  • 所有线程在await()前写入的共享数据,
  • 在屏障动作中可见,
  • 并且在其他线程继续执行后也可见。

✅ 无需额外同步!


六、使用示例回顾(你的代码)

// N 个 worker 线程并行处理矩阵行barrier=newCyclicBarrier(N,()->mergeRows(...));Worker.run(){while(!done()){processRow(myRow);barrier.await();// 等待所有行处理完}}
  • 每轮:所有线程处理一行 → 等待 → 合并结果 → 下一轮。
  • 如果mergeRows()发现解已找到,done()返回 true,线程退出。
  • 完美体现“循环同步 + 屏障动作”。

七、总结:一句话理解 CyclicBarrier

它是一个可重复使用的“集合点”:N 个线程各自完成任务后在此汇合,全部到齐才一起继续;支持在汇合时执行一个汇总操作,并且任何一人掉队(中断/超时)则全员失败。

它的设计精妙之处在于:

  • Generation隔离不同轮次;
  • ReentrantLock + Condition实现高效等待/唤醒;
  • 提供强一致性语义和灵活的扩展点(barrier action)。

这也是 Doug Lea 并发设计的经典之作。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 19:48:05

救命神器2026 TOP10 AI论文工具:本科生毕业论文写作全测评

救命神器2026 TOP10 AI论文工具:本科生毕业论文写作全测评 2026年学术写作工具测评:为什么你需要这份榜单? 随着人工智能技术的不断进步,AI论文工具已经成为本科生撰写毕业论文的重要辅助手段。然而,面对市场上种类繁多…

作者头像 李华
网站建设 2026/4/30 21:34:33

2026爆火6款AI论文工具:一键生成初稿,写论文从未如此简单!

前言:2026毕业季倒计时,你的论文还在“难产”吗? 凌晨3点的图书馆、导师第8次打回的修改意见、查重率40%的红色警告、离截止日只剩72小时却连初稿框架都没搭好…… 如果你正被这些“论文噩梦”缠上,那这篇文章就是你的24小时急救…

作者头像 李华
网站建设 2026/5/6 10:56:32

netsh.exe文件损坏丢失找不到 打不开 下载方法分享

在使用电脑系统时经常会出现丢失找不到某些文件的情况,由于很多常用软件都是采用 Microsoft Visual Studio 编写的,所以这类软件的运行需要依赖微软Visual C运行库,比如像 QQ、迅雷、Adobe 软件等等,如果没有安装VC运行库或者安装…

作者头像 李华
网站建设 2026/4/30 21:32:54

全网最全专科生必备AI论文软件TOP8:开题报告文献综述神器测评

全网最全专科生必备AI论文软件TOP8:开题报告文献综述神器测评 2026年专科生必备AI论文软件测评:为何值得一看? 在当前学术写作日益智能化的背景下,专科生群体面临着开题报告、文献综述等环节的重重挑战。传统的写作方式不仅效率低…

作者头像 李华