CyclicBarrier:人齐了,老司机就可以发车了!

上一篇咱讲了 CountDownLatch 可以解决多个线程同步的问题,相比于 join 来说它的应用范围更广,不仅可以应用在线程上,还可以应用在线程池上。然而 CountDownLatch 却是一次性的计数器,以王者农药来说,咱们不可能一场团战就决定比赛的输赢,所以在某些场景下,咱们是需要重复使用某个等待功能的,这就是我们今天要介绍的另一个主角——CyclicBarrier。

CyclicBarrier

CyclicBarrier 翻译为中文是循环(Cyclic)栅栏(Barrier)的意思,它的大概含义是实现一个可循环利用的屏障。

image.png


CyclicBarrier 作用是让一组线程相互等待,当达到一个共同点时,所有之前等待的线程再继续执行,且 CyclicBarrier 功能可重复使用。

20181218144511688.gif

举个栗子

比如磊哥要坐班车回老家,因为中途不允许上、下乘客,所以营运的公司为了收益最大化,就会等人满之后再发车。像这种等人坐满就发一班车的场景,就是 CyclicBarrier 所擅长的,因为它可以重复使用(不像 CountDownLatch 那样只能用一次)。

image.png

CyclicBarrier VS CountDownLatch

CountDownLatch:一个或者多个线程,等待另外 N 个线程完成某个事情之后才能执行。

CountDownLatch 就像玩王者农药开局的加载一样,所有人要等待其他人都加载 100% 之后才能开始游戏。

image.png

CyclicBrrier:N 个线程相互等待,直到有足够数量的线程都到达屏障点之后,之前等待的线程就可以继续执行了。

CyclicBrrier 就像老司机开车一样,如果车上还有空余的座位,那么所有人都得等着,直到座位被坐满之后,老司机才会发车。

老司机发车.gif

CyclicBarrier使用 import java.util.Date; import java.util.Random; import java.util.concurrent.*; public class CyclicBarrierExample { public static void main(String[] args) { // 创建 CyclicBarrier final CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable() { @Override public void run() { System.out.println("人满了,准备发车:" + new Date()); } }); // 线程调用的任务 Runnable runnable = new Runnable() { @Override public void run() { // 生成随机数 1-3 int randomNumber = new Random().nextInt(3) + 1; // 进入任务 System.out.println(String.format("我是:%s 再走:%d 秒就到车站了,现在时间:%s", Thread.currentThread().getName(), randomNumber, new Date())); try { // 模拟执行 TimeUnit.SECONDS.sleep(randomNumber); // 调用 CyclicBarrier cyclicBarrier.await(); // 任务执行 System.out.println(String.format("线程:%s 上车,时间:%s", Thread.currentThread().getName(), new Date())); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }; // 创建线程池 ExecutorService threadPool = Executors.newFixedThreadPool(10); // 执行任务 1 threadPool.submit(runnable); // 执行任务 2 threadPool.submit(runnable); // 执行任务 3 threadPool.submit(runnable); // 执行任务 4 threadPool.submit(runnable); // 等待所有任务执行完终止线程池 threadPool.shutdown(); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsswyj.html