当前位置: 代码迷 >> 综合 >> JUC-7.3-线程协作-CyclicBarrier
  详细解决方案

JUC-7.3-线程协作-CyclicBarrier

热度:20   发布时间:2023-12-05 18:28:15.0

CyclicBarrier 循环栅栏同样是一个线程协作工具,和 CountDownLatch 很像,都能阻塞一组线程

作用

当有大量线程相互配合,分别计算不同任务,并且需要最后统一汇总的时候,我们可以使用 CyclicBarrier,CyclicBarrier 可以构造一个集结点,当某一个线程执行了await(),它就会到集结点等待,直到所有线程都到了集结点,那么该栅栏就被撤销,所有线程再统一出发,继续执行剩下的任务.

常用方法

  • 构造函数,有两个参数,第一个是等待线程的数量,第二个是一个 Runnable 的实现
  • await(): 调用的线程进入阻塞状态等待

代码示例

@Slf4j
public class CyclicBarrierDemo {public static void main(String[] args) {CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> log.info("所有线程都到了..."));for (int i = 0; i < 5; i++) {new Thread(new Task(i + 1, cyclicBarrier)).start();}}@AllArgsConstructor@Slf4jstatic class Task implements Runnable{private int id;private CyclicBarrier cyclicBarrier;@Overridepublic void run() {log.info("当前线程正在执行,id:[{}]", id);try {Thread.sleep((long) (Math.random() * 10000));cyclicBarrier.await();log.info("所有线程都到了,继续执行,当前线程id:{}",id);} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}}}

控制台输出如下:

10:40:34.645 [Thread-1] INFO com.learning.java.cooperation.CyclicBarrierDemo$Task - 当前线程正在执行,id:[2]
10:40:34.645 [Thread-0] INFO com.learning.java.cooperation.CyclicBarrierDemo$Task - 当前线程正在执行,id:[1]
10:40:34.645 [Thread-2] INFO com.learning.java.cooperation.CyclicBarrierDemo$Task - 当前线程正在执行,id:[3]
10:40:34.645 [Thread-3] INFO com.learning.java.cooperation.CyclicBarrierDemo$Task - 当前线程正在执行,id:[4]
10:40:34.645 [Thread-4] INFO com.learning.java.cooperation.CyclicBarrierDemo$Task - 当前线程正在执行,id:[5]
10:40:43.843 [Thread-4] INFO com.learning.java.cooperation.CyclicBarrierDemo - 所有线程都到了...
10:40:43.843 [Thread-4] INFO com.learning.java.cooperation.CyclicBarrierDemo$Task - 所有线程都到了,继续执行,当前线程id:5
10:40:43.843 [Thread-2] INFO com.learning.java.cooperation.CyclicBarrierDemo$Task - 所有线程都到了,继续执行,当前线程id:3
10:40:43.843 [Thread-0] INFO com.learning.java.cooperation.CyclicBarrierDemo$Task - 所有线程都到了,继续执行,当前线程id:1
10:40:43.843 [Thread-1] INFO com.learning.java.cooperation.CyclicBarrierDemo$Task - 所有线程都到了,继续执行,当前线程id:2
10:40:43.843 [Thread-3] INFO com.learning.java.cooperation.CyclicBarrierDemo$Task - 所有线程都到了,继续执行,当前线程id:4

首先声明一个数量是 5 的 CyclicBarrier, 然后新建5个线程,之后都调用 await() 方法,等到5个线程都调用 await() 方法之后,就会执行构造中传入的 Runnable 的实现, 然后所有线程唤醒,继续执行

对比 CountDownLatch

  1. 作用不同: CyclicBarrier 要等到固定数量的线程都到达了栅栏位置才能继续执行, CountDownLatch 只需要在计数器为0的时候就可以继续执行,也就是说 CountDownLatch 用于事件,而 CyclicBarrier 是用于线程的
  2. 可重用性不同: CountDownLatch 再倒数触发门闩打开之后就不能再重用了,而 CyclicBarrier 是可以重复使用的
  相关解决方案