- CyclicBarrier的介绍
类CyclicBarrier不仅有CountDownLatch所具有的功能,还可以是啊县屏障等待的功能,也就是阶段性同步,它在使用上的意义在与可以循环地实现线程要一起做任务的目标,而不是像类CountDownLatch一样,仅仅支持一次线程与同步点阻塞的特性。
CyclicBarrier与CountDownLatch的区别:
1、CountDownLatch是一个线程或者多个线程,等待两一个线程或者多个线程完成某件事情之后才能继续执行。
2、CyclicBarrier是指多个线程之间互相等待,任何一个线程完成之前,所有的线程都必须等待。
- 实例
模拟田径比赛的CyclicBarrier版本
package com.wjg.unit_2_2_1; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class Run { public static void main(String[] args) throws InterruptedException { CyclicBarrier barrier = new CyclicBarrier(10, new Runnable() { @Override public void run() { System.out.println("全部准备就绪!"); } }); Run run = new Run(); for (int i = 0; i < barrier.getParties(); i++) { MyThread thread = run.new MyThread(barrier); thread.setName("运动员"+(i+1)); thread.start(); } } public class MyThread extends Thread{ private CyclicBarrier barrier; public MyThread(CyclicBarrier barrier) { super(); this.barrier = barrier; } @Override public void run() { try { Thread.sleep((int)Math.random()*1000); System.out.println(this.getName()+"到了"); barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } } }
执行结果:
运动员1到了
运动员2到了
运动员3到了
运动员4到了
运动员5到了
运动员6到了
运动员7到了
运动员10到了
运动员9到了
运动员8到了
全部准备就绪!
- 模拟篮球场的3V3接波场景
package com.wjg.unit_2_2_1; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class Run { public static void main(String[] args) throws InterruptedException { CyclicBarrier barrier = new CyclicBarrier(3, new Runnable() { @Override public void run() { System.out.println("3人小队组队完毕,可以接波了"); } }); Run run = new Run(); for (int i = 0; i < 9; i++) { MyThread thread = run.new MyThread(barrier); thread.setName("玩家"+(i+1)); thread.start(); } } public class MyThread extends Thread{ private CyclicBarrier barrier; public MyThread(CyclicBarrier barrier) { super(); this.barrier = barrier; } @Override public void run() { try { Thread.sleep((int)Math.random()*1000); System.out.println(this.getName()+"到达球场,等待凑齐三人"); barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } } }
执行结果:
玩家2到达球场,等待凑齐三人
玩家5到达球场,等待凑齐三人
玩家4到达球场,等待凑齐三人
3人小队组队完毕,可以接波了
玩家3到达球场,等待凑齐三人
玩家1到达球场,等待凑齐三人
玩家6到达球场,等待凑齐三人
3人小队组队完毕,可以接波了
玩家7到达球场,等待凑齐三人
玩家8到达球场,等待凑齐三人
玩家9到达球场,等待凑齐三人
3人小队组队完毕,可以接波了
- 方法getNumerWaiting()
此方法的作用是获得由几个线程已经到达了屏障点。
- 方法isBroken()
查询此屏障是否处于损坏状态,比如其中一个线程执行抛出了异常。则isBroken为true。
- 方法await(long timeout,TimeUnit unit)
如果在执行的时间内达到parties的数量,则程序继续往下运行,否如如果出现超市,则抛出TimeoutException异常。
- 方法getParties()
此方法作用是获得parties的个数。
- 方法reset()
此方法作用是重置屏障,如果已经处于等待的线程会抛出BrokenBarrierException异常。