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

输出的信息看着有点乱,给大家理一理,员工5遇到急事,拿起筷子就是吃,这样好么,当然不好,他这么做了,后面看他这么做了都跟着这么做(这种场景是不是很熟悉,有一个人拿起筷子先吃起来,其他人都跟着上了),直接不等其他人了,拿起筷子就开吃了。CyclicBarrier遇到这种情况就是这么处理的。前面4个员工都在await()处等待着,员工5也在await()上等待着,等了1秒(TimeUnit.SECONDS.sleep(1);),接了个电话,然后给员工5发送中断信号后(t.interrupt();),员工5的await()方法会触发InterruptedException异常,此时其他等待中的前4个员工,看着5开吃了,自己立即也不等了,内部从await()方法中触发BrokenBarrierException异常,然后也开吃了,后面的6/7/8/9/10员工来了以后发现大家都开吃了,自己也不等了,6-10员工调用await()直接抛出了BrokenBarrierException异常,然后继续向下。

结论:

内部有一个人把规则破坏了(接收到中断信号),其他人都不按规则来了,不会等待了

接收到中断信号的线程,await方法会触发InterruptedException异常,然后被唤醒向下运行

其他等待中 或者后面到达的线程,会在await()方法上触发BrokenBarrierException异常,然后继续执行

示例5:其中一个人只愿意等待5秒

基于示例1,员工1只愿意等的5秒,5s后如果大家还没到期,自己要开吃了,员工1开吃了,其他人会怎么样呢?

package com.itsoku.chat15; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * 微信公众号:javacode2018,获取年薪50万java课程 */ public class Demo5 { public static CyclicBarrier cyclicBarrier = new CyclicBarrier(10); public static class T extends Thread { int sleep; public T(String name, int sleep) { super(name); this.sleep = sleep; } @Override public void run() { long starTime = 0, endTime = 0; try { //模拟休眠 TimeUnit.SECONDS.sleep(sleep); starTime = System.currentTimeMillis(); //调用await()的时候,当前线程将会被阻塞,需要等待其他员工都到达await了才能继续 System.out.println(this.getName() + "到了!"); if (this.getName().equals("员工1")) { cyclicBarrier.await(5, TimeUnit.SECONDS); } else { cyclicBarrier.await(); } } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } catch (TimeoutException e) { e.printStackTrace(); } endTime = System.currentTimeMillis(); System.out.println(this.getName() + ",sleep:" + this.sleep + " 等待了" + (endTime - starTime) + "(ms),开始吃饭了!"); } } public static void main(String[] args) throws InterruptedException { for (int i = 1; i <= 10; i++) { T t = new T("员工" + i, i); t.start(); } } }

输出:

员工1到了! 员工2到了! 员工3到了! 员工4到了! 员工5到了! 员工6到了! 员工1,sleep:1 等待了5001(ms),开始吃饭了! 员工5,sleep:5 等待了1001(ms),开始吃饭了! java.util.concurrent.TimeoutException at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:257) at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:435) at com.itsoku.chat15.Demo5$T.run(Demo5.java:32) java.util.concurrent.BrokenBarrierException at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:250) at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362) at com.itsoku.chat15.Demo5$T.run(Demo5.java:34) java.util.concurrent.BrokenBarrierException at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207) at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362) at com.itsoku.chat15.Demo5$T.run(Demo5.java:34) 员工6,sleep:6 等待了2(ms),开始吃饭了! java.util.concurrent.BrokenBarrierException 员工2,sleep:2 等待了4002(ms),开始吃饭了! at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:250) 员工3,sleep:3 等待了3001(ms),开始吃饭了! at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362) 员工4,sleep:4 等待了2001(ms),开始吃饭了! at com.itsoku.chat15.Demo5$T.run(Demo5.java:34) java.util.concurrent.BrokenBarrierException at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:250) at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362) at com.itsoku.chat15.Demo5$T.run(Demo5.java:34) java.util.concurrent.BrokenBarrierException at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:250) at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362) at com.itsoku.chat15.Demo5$T.run(Demo5.java:34) java.util.concurrent.BrokenBarrierException 员工7到了! at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207) 员工7,sleep:7 等待了0(ms),开始吃饭了! at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362) at com.itsoku.chat15.Demo5$T.run(Demo5.java:34) 员工8到了! 员工8,sleep:8 等待了0(ms),开始吃饭了! java.util.concurrent.BrokenBarrierException at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207) at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362) at com.itsoku.chat15.Demo5$T.run(Demo5.java:34) 员工9到了! java.util.concurrent.BrokenBarrierException 员工9,sleep:9 等待了0(ms),开始吃饭了! at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207) at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362) at com.itsoku.chat15.Demo5$T.run(Demo5.java:34) java.util.concurrent.BrokenBarrierException 员工10到了! at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207) at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362) 员工10,sleep:10 等待了0(ms),开始吃饭了! at com.itsoku.chat15.Demo5$T.run(Demo5.java:34)

从输出结果中我们可以看到:1等待5秒之后,开吃了,其他等待人都开吃了,后面来的人不等待,直接开吃了。

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

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