对 Go 语言中循环屏障 CyclicBarrier 的理解

        同步屏障 (Barrier) 是并发编程中的一种同步方法。对于一组 goroutine ,程序中的一个同步屏障意味着任何 goroutine 执行到此后都必须等待,直到所有的 goroutine 都达到此点才可继续执行下文。

        Barrier 无论是翻译成屏障、障碍还是栅栏,都很形象,就是一道拦截坝,拦截一组对象,等对象齐了才打开它。

        CyclicBarrier 允许一组 goroutine 彼此等待,到达一个共同的检查点,然后到达下一个同步点,循环使用。因为它可以被重复使用,所以叫做循环屏障,或者叫作可循环使用的屏障。具体的机制是,大家都在屏障前等待,等全部到齐了,就打开屏障放行。

1. CyclicBarrier 的使用场景

        你可能会觉得,CyclicBarrier 和 WaitGroup 的功能有点类似。确实是这样的。不过,CyclicBarrier 更适合用在 “数量固定的 goroutine 等待到达同一个检查点” 的场景中,而且在放行 goroutine 之后,CyclicBarrier 可以被重复利用,不像 WaitGroup 被重用时必须小心翼翼,避免发生 panic。

        在处理可重用的多个 goroutine 等待到达同一个检查点的场景时,CyclicBarrier 和 WaitGroup 方法调用的对应关系如下图所示:

        在重复使用 WaitGroup 的时候,wg.Add 和 wg.Wait 的下一次调用并不能很好地同步,所以这也是 CyclicBarrier 擅长处理的场景。

        可以看到,如果使用 WaitGroup 实现的话,调用比较复杂,不像使用 CyclicBarrier 那么清爽。更重要的是,如果想重用 WaitGroup, 还要保证将 WaitGroup 的计数值重置到 n 时不会出现并发问题。

        WaitGroup 更适合用在 “一个 goroutine 等待一组 goroutine 到达同一个检查点” 的场景中,或者是不需要重用的场景中。

        其实上面的区别还不是最关键的,这两个同步原语最重要的不同在于:CyclicBarrier 的参与者之间相互等待ÿ

  • 20
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
CyclicBarrier 是 Java 的一个同步工具类,它允许一组线程互相等待,直到所有线程都到达某个屏障点,然后再一起继续执行。CyclicBarrier 可以循环使用,因此称之为循环屏障。 下面是 CyclicBarrier 工具类的基本使用示例: ```java import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierDemo { public static void main(String[] args) { // 创建一个 CyclicBarrier 实例,指定等待线程数和屏障动作 CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> { System.out.println("所有线程已到达屏障点,开始执行屏障动作"); }); // 创建 3 个线程,模拟多个线程同时到达屏障点 for (int i = 0; i < 3; i++) { new Thread(() -> { try { System.out.println(Thread.currentThread().getName() + " 已到达屏障点,等待其他线程"); cyclicBarrier.await(); // 等待其他线程到达屏障点 System.out.println(Thread.currentThread().getName() + " 继续执行"); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } }).start(); } } } ``` 上述代码,我们创建了一个 CyclicBarrier 实例,指定等待线程数和屏障动作。然后创建了 3 个线程,模拟多个线程同时到达屏障点,每个线程到达屏障点后等待其他线程,直到所有线程到达屏障点,才会继续执行。 在 CyclicBarrier 的构造函数,我们指定了等待线程数为 3,也就是说,只有当 3 个线程都到达屏障点时,才会执行屏障动作。屏障动作是一个 Runnable 对象,它会在所有线程到达屏障点后执行一次。 在每个线程执行的代码,我们调用了 CyclicBarrier 的 await() 方法,等待其他线程到达屏障点。当所有线程都到达屏障点后,await() 方法会返回,线程继续执行。 需要注意的是,CyclicBarrier 的 await() 方法可能会抛出 InterruptedException 和 BrokenBarrierException 异常,因此需要在 catch 块处理这两个异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mindfulness code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值