java高并发系列 - 第17天:JUC中的循环栅栏CyclicBarrier常见的6种使用场景及代码示例 (2)

输出:

员工10,sleep:10 等待了0(ms),开始吃饭了! 员工5,sleep:5 等待了5000(ms),开始吃饭了! 员工6,sleep:6 等待了4000(ms),开始吃饭了! 员工9,sleep:9 等待了1001(ms),开始吃饭了! 员工4,sleep:4 等待了6000(ms),开始吃饭了! 员工3,sleep:3 等待了7000(ms),开始吃饭了! 员工1,sleep:1 等待了9001(ms),开始吃饭了! 员工2,sleep:2 等待了8000(ms),开始吃饭了! 员工8,sleep:8 等待了2001(ms),开始吃饭了! 员工7,sleep:7 等待了3000(ms),开始吃饭了! 员工10,sleep:10 等待了0(ms),去下一景点的路上! 员工1,sleep:1 等待了8998(ms),去下一景点的路上! 员工5,sleep:5 等待了4999(ms),去下一景点的路上! 员工4,sleep:4 等待了5999(ms),去下一景点的路上! 员工3,sleep:3 等待了6998(ms),去下一景点的路上! 员工2,sleep:2 等待了7998(ms),去下一景点的路上! 员工9,sleep:9 等待了999(ms),去下一景点的路上! 员工8,sleep:8 等待了1999(ms),去下一景点的路上! 员工7,sleep:7 等待了2999(ms),去下一景点的路上! 员工6,sleep:6 等待了3999(ms),去下一景点的路上!

坑,又是员工10最慢,要提升效率了,不能吃的太多,得减肥。

代码中CyclicBarrier相当于使用了2次,第一次用于等待所有人到达后开饭,第二次用于等待所有人上车后驱车去下一景点。注意一些先到的员工会在其他人到达之前,都处于等待状态(cyclicBarrier.await();会让当前线程阻塞),无法干其他事情,等到最后一个人到了会唤醒所有人,然后继续。

CyclicBarrier内部相当于有个计数器(构造方法传入的),每次调用await();后,计数器会减1,并且await()方法会让当前线程阻塞,等待计数器减为0的时候,所有在await()上等待的线程被唤醒,然后继续向下执行,此时计数器又会被还原为创建时的值,然后可以继续再次使用。

示例3:最后到的人给大家上酒,然后开饭

还是示例1中的例子,员工10是最后到达的,让所有人都久等了,那怎么办,得给所有人倒酒,然后开饭,代码如下:

package com.itsoku.chat15; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.TimeUnit; /** * 微信公众号:javacode2018,获取年薪50万java课程 */ public class Demo3 { public static CyclicBarrier cyclicBarrier = new CyclicBarrier(10, () -> { //模拟倒酒,花了2秒,又得让其他9个人等2秒 try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "说,不好意思,让大家久等了,给大家倒酒赔罪!"); }); public static class T extends Thread { int sleep; public T(String name, int sleep) { super(name); this.sleep = sleep; } @Override public void run() { try { //模拟休眠 TimeUnit.SECONDS.sleep(sleep); long starTime = System.currentTimeMillis(); //调用await()的时候,当前线程将会被阻塞,需要等待其他员工都到达await了才能继续 cyclicBarrier.await(); long endTime = System.currentTimeMillis(); System.out.println(this.getName() + ",sleep:" + this.sleep + " 等待了" + (endTime - starTime) + "(ms),开始吃饭了!"); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException { for (int i = 1; i <= 10; i++) { new T("员工" + i, i).start(); } } }

输出:

员工10说,不好意思,让大家久等了,给大家倒酒赔罪! 员工10,sleep:10 等待了2000(ms),开始吃饭了! 员工1,sleep:1 等待了11000(ms),开始吃饭了! 员工2,sleep:2 等待了10000(ms),开始吃饭了! 员工5,sleep:5 等待了7000(ms),开始吃饭了! 员工7,sleep:7 等待了5000(ms),开始吃饭了! 员工9,sleep:9 等待了3000(ms),开始吃饭了! 员工4,sleep:4 等待了8000(ms),开始吃饭了! 员工3,sleep:3 等待了9001(ms),开始吃饭了! 员工8,sleep:8 等待了4001(ms),开始吃饭了! 员工6,sleep:6 等待了6001(ms),开始吃饭了!

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

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