2026/4/16 23:58:29
网站建设
项目流程
做的新网站网上搜不到,网站建设标语文案,赣州网站建设服务,音乐类网站开发CyclicBarrier 是 Java 并发包中一个可重用的同步辅助工具#xff0c;用于让一组固定数量的线程互相等待#xff0c;直到所有线程都到达某个“屏障点”#xff08;barrier point#xff09;#xff0c;然后一起继续执行。它的名字中的 “Cyclic”#xff08;循环#xf…CyclicBarrier是 Java 并发包中一个可重用的同步辅助工具用于让一组固定数量的线程互相等待直到所有线程都到达某个“屏障点”barrier point然后一起继续执行。它的名字中的“Cyclic”循环正是因为它可以在一次使用后重置并重复使用。下面从核心思想、内部机制、关键特性、与 CountDownLatch 的区别、内存语义五个方面帮你彻底理解。一、核心思想多线程“齐步走”想象一个班级做操老师喊“所有人到操场集合”学生 A、B、C……陆续到达但必须等最后一个同学到齐才能开始做操。做完一轮后老师又喊“再来一轮”大家再次集合 →这就是“循环”。在程序中每个线程执行一部分工作然后调用barrier.await()等待当所有 N 个线程都调用了await()屏障“放行”所有线程继续下次还能再用同一个CyclicBarrier。✅典型场景并行迭代计算如 Jacobi 迭代、多阶段任务同步。二、内部实现机制1. 核心组件privatefinalReentrantLocklocknewReentrantLock();privatefinalConditiontriplock.newCondition();// 等待/唤醒的条件privatefinalintparties;// 总线程数固定privateintcount;// 当前轮次剩余未到达的线程数privateGenerationgeneration;// 表示当前“代”一轮privatefinalRunnablebarrierCommand;// 屏障动作可选2.Generation区分“轮次”每次屏障触发tripped或重置reset就创建一个新的Generation对象。所有等待的线程都关联到同一个 generation。如果某轮被中断如超时、异常该 generation 被标记为broken true。新一轮开始时generation指向新对象旧的被废弃。 作用防止“跨轮次”的线程互相干扰比如上一轮的线程误唤醒下一轮的。3.dowait()核心等待逻辑intindex--count;// 倒计数if(index0){// 最后一个线程到达执行 barrierCommand如果有;nextGeneration();// 重置 count新建 generationsignalAll()}else{// 不是最后一个进入等待trip.await();// 或 awaitNanos()}关键行为最后一个到达的线程负责执行barrierCommand如合并结果调用trip.signalAll()唤醒所有等待者创建新一代nextGeneration()。其他线程阻塞在trip.await()直到被唤醒。三、关键特性1.All-or-Nothing全有或全无如果任何一个线程在等待时被中断、超时、或调用reset()那么所有等待的线程都会抛出BrokenBarrierException并且 barrier 进入broken 状态。这保证了“要么全部通过要么全部失败”避免部分线程卡住。2.Barrier Action屏障动作可在构造时传入一个RunnablenewCyclicBarrier(N,()-mergeResults());该动作由最后一个到达的线程执行在唤醒其他人之前。常用于汇总本轮结果、更新全局状态。3.返回到达序号intarrivalIndexbarrier.await();返回值parties - 1表示第一个到达0表示最后一个。可用于指定某个线程如if (await() 0)执行日志、清理等操作。4.可重置resetbarrier.reset();// 立即打破当前轮次开启新轮次所有当前等待的线程会收到BrokenBarrierException。之后可以重新开始新一轮同步。四、与CountDownLatch的本质区别特性CyclicBarrierCountDownLatch用途多线程互相等待N 对 N一个/多个线程等其他线程完成1 对 N 或 N 对 1可重用✅ 是cyclic❌ 否one-shot触发者所有参与线程自己调用await()其他线程调用countDown()屏障动作✅ 支持最后一个线程执行❌ 不支持失败模型All-or-nothing全失败单独失败不影响他人底层实现ReentrantLock ConditionAQS 共享模式简单记用CountDownLatch“我等你们干完”协调者模式。用CyclicBarrier“我们互相等一起走”协作模式。五、内存可见性Memory ConsistencyJava 内存模型保证以下happens-before关系线程 A 在await()之前的操作→happens-before屏障动作barrier action的执行→happens-before其他线程从await()返回后的操作这意味着所有线程在await()前写入的共享数据在屏障动作中可见并且在其他线程继续执行后也可见。✅ 无需额外同步六、使用示例回顾你的代码// N 个 worker 线程并行处理矩阵行barriernewCyclicBarrier(N,()-mergeRows(...));Worker.run(){while(!done()){processRow(myRow);barrier.await();// 等待所有行处理完}}每轮所有线程处理一行 → 等待 → 合并结果 → 下一轮。如果mergeRows()发现解已找到done()返回 true线程退出。完美体现“循环同步 屏障动作”。七、总结一句话理解 CyclicBarrier它是一个可重复使用的“集合点”N 个线程各自完成任务后在此汇合全部到齐才一起继续支持在汇合时执行一个汇总操作并且任何一人掉队中断/超时则全员失败。它的设计精妙之处在于用Generation隔离不同轮次用ReentrantLock Condition实现高效等待/唤醒提供强一致性语义和灵活的扩展点barrier action。这也是 Doug Lea 并发设计的经典之作。