员工1调用有参await方法等待5秒之后,触发了TimeoutException异常,然后继续向下运行,其他的在5开吃之前已经等了一会的的几个员工,他们看到5开吃了,自己立即不等待了,也开吃了(他们的await抛出了BrokenBarrierException异常);还有几个员工在5开吃之后到达的,他们直接不等待了,直接抛出BrokenBarrierException异常,然后也开吃了。
结论:
等待超时的方法
public int await(long timeout, TimeUnit unit) throws InterruptedException,BrokenBarrierException,TimeoutException内部有一个人把规则破坏了(等待超时),其他人都不按规则来了,不会等待了
等待超时的线程,await方法会触发TimeoutException异常,然后被唤醒向下运行
其他等待中或者后面到达的线程,会在await()方法上触发BrokenBarrierException异常,然后继续执行
示例6:重建规则示例5中改造一下,员工1等待5秒超时之后,开吃了,打破了规则,先前等待中的以及后面到达的都不按规则来了,都拿起筷子开吃。过了一会,导游重新告知大家,要按规则来,然后重建了规则,大家都按规则来了。
代码如下:
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 Demo6 { public static CyclicBarrier cyclicBarrier = new CyclicBarrier(10); //规则是否已重建 public static boolean guizhe = false; 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 (!guizhe) { if (this.getName().equals("员工1")) { cyclicBarrier.await(5, TimeUnit.SECONDS); } else { cyclicBarrier.await(); } } 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(); } //等待10秒之后,重置,重建规则 TimeUnit.SECONDS.sleep(15); cyclicBarrier.reset(); guizhe = true; System.out.println("---------------大家太皮了,请大家按规则来------------------"); //再来一次 for (int i = 1; i <= 10; i++) { T t = new T("员工" + i, i); t.start(); } } }输出:
员工1到了! 员工2到了! 员工3到了! 员工4到了! 员工5到了! 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.Demo6$T.run(Demo6.java:36) 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.Demo6$T.run(Demo6.java:38) 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.Demo6$T.run(Demo6.java:38) 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.Demo6$T.run(Demo6.java:38) 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.Demo6$T.run(Demo6.java:38) 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.Demo6$T.run(Demo6.java:38) 员工6到了! 员工1,sleep:1 等待了5002(ms),开始吃饭了! 员工6,sleep:6 等待了4(ms),开始吃饭了! 员工4,sleep:4 等待了2004(ms),开始吃饭了! 员工5,sleep:5 等待了1004(ms),开始吃饭了! 员工3,sleep:3 等待了3002(ms),开始吃饭了! 员工2,sleep:2 等待了4004(ms),开始吃饭了! 员工7到了! 员工7,sleep:7 等待了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.Demo6$T.run(Demo6.java:38) 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.Demo6$T.run(Demo6.java:38) 员工8到了! 员工8,sleep:8 等待了0(ms),开始吃饭了! java.util.concurrent.BrokenBarrierException 员工9到了! at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207) 员工9,sleep:9 等待了0(ms),开始吃饭了! at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362) at com.itsoku.chat15.Demo6$T.run(Demo6.java:38) java.util.concurrent.BrokenBarrierException 员工10到了! at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207) 员工10,sleep:10 等待了0(ms),开始吃饭了! at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362) at com.itsoku.chat15.Demo6$T.run(Demo6.java:38) ---------------大家太皮了,请大家按规则来------------------ 员工1到了! 员工2到了! 员工3到了! 员工4到了! 员工5到了! 员工6到了! 员工7到了! 员工8到了! 员工9到了! 员工10到了! 员工10,sleep:10 等待了0(ms),开始吃饭了! 员工1,sleep:1 等待了9000(ms),开始吃饭了! 员工2,sleep:2 等待了8000(ms),开始吃饭了! 员工3,sleep:3 等待了6999(ms),开始吃饭了! 员工7,sleep:7 等待了3000(ms),开始吃饭了! 员工6,sleep:6 等待了4000(ms),开始吃饭了! 员工5,sleep:5 等待了5000(ms),开始吃饭了! 员工4,sleep:4 等待了6000(ms),开始吃饭了! 员工9,sleep:9 等待了999(ms),开始吃饭了! 员工8,sleep:8 等待了1999(ms),开始吃饭了!