电话
400 9058 355
该用CyclicBarrier而非CountDownLatch时:需多线程彼此等待、同时出发,且需重复使用;CyclicBarrier支持循环重用,适用于分段执行+同步汇合+迭代场景。
CyclicBarrier 而不是 CountDownLatch
当多个线程需要「彼此等待、同时出发」时,CyclicBarrier 是更自然的选择。比如并行计算中,每个线程处理数据块后必须等全部完成,再一起进入下一轮聚合;而 CountDownLatch 更适合「一个线程等其他线程全部结束」这种单向等待。
关键区别在于重用性:CyclicBarrier 可被重复 await() 多次(名字里的 “Cyclic” 就是这个意思),CountDownLatch 一旦计数归零就不可重置。
CountDownLatch 更轻量)、线程间无协作依赖(可能根本不需要屏障)CyclicBarrier 的构造参数是参与
CountDownLatch(int) 的语义混淆CyclicBarrier 的 Runnable 回调在哪个线程执行当最后一个线程调用 await() 并触发屏障释放时,你传入的 Runnable(即 barrier action)由「那个最后到达的线程」同步执行 —— 不是新线程,也不是主线程,更不是固定线程池中的某一个。
这意味着:
RuntimeException),该异常会包装为 BrokenBarrierException 并传播给所有正在 await() 的线程null,避免无谓开销CyclicBarrier.await() 的异常await() 方法声明抛出两种受检异常:InterruptedException 和 BrokenBarrierException。后者表示屏障被破坏(比如某个线程超时退出、中断,或回调抛异常),此时整个屏障失效,后续调用都会立即抛出该异常。
典型处理方式:
InterruptedException 并考虑是否恢复中断状态(Thread.currentThread().interrupt())BrokenBarrierException 通常意味着协作已失败,应中止当前任务或重置屏障(调用 reset(),但要注意:这会唤醒所有等待线程并让它们收到 BrokenBarrierException)await(long, TimeUnit)),还要处理 TimeoutException,它同样会导致屏障进入破损状态try {
barrier.await(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return; // 或抛出自定义异常
} catch (TimeoutException e) {
System.err.println("Barrier timeout, aborting");
barrier.reset(); // 可选:尝试恢复,但需确保其他线程也配合
} catch (BrokenBarrierException e) {
System.err.println("Barrier broken, check upstream failure");
return;
}
Phaser 比,为什么有时还得选 CyclicBarrier
Phaser 功能更强大(支持动态注册/注销线程、分阶段、树形结构),但复杂度和开销也更高。如果你只需要固定数量线程的简单「到齐即发」,CyclicBarrier 更直观、内存占用更小、JVM 对其优化更成熟。
真实权衡点:
CyclicBarrier 足够Phaser
Phaser 的 onAdvance() 更灵活CyclicBarrier 的 await() 在 HotSpot 下有专门优化路径别为了“听起来更现代”而换 Phaser——多数批量同步场景里,CyclicBarrier 的简洁性本身就是稳定性保障。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...