CyclicBarrier介绍及使用说明

CycLicBarrier是一个同步辅助类,它控制一组线程互相等待,直到到达设定好的公共屏障点,在涉及一组固定大小的线程池的程序中,这些线程必须不时的互相等待,此时使用CycLicBarrier非常适合,因为barrier在释放等待线程后可以重用,所以被称为循环屏障(cyclcbarrier )。

cycLicBarrier类似于CountDownLatch,也可以视作一个计数锁,不同的是,cyclicBarrier调用await()方法时,是将进入阻塞状态的线程数的数量加一,当线程数达到了cyclicBarrier初始化时设定的数目时,所有阻塞状态的线程呗唤醒并继续执行,cyclicBarrier的作用如同其名,可以理解成一个屏障点,只有当所有的线程都到达这个屏障点时,才能一起通过(继续执行后续操作),cyclicBarrier初始化时可以带一个Runnable的参数,此参数,这个Runnable任务在一组线程中的最后一个线程到达(barrier)之后,但在释放所有线程(阻塞线程被唤醒)之前执行,该命令只在每个屏障点运行一次。

**构造方法摘要**CyclicBarrier(int parties) 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在启动 barrier 时执行预定义的操作。CyclicBarrier(int parties, Runnable barrierAction) 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。 **方法摘要**int await() 在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。int await(long timeout, TimeUnit unit) 在所有参与者都已经在此屏障上调用 await 方法之前将一直等待,或者超出了指定的等待时间。int getNumberWaiting() 返回当前在屏障处等待的参与者数目。int getParties() 返回要求启动此 barrier 的参与者数目。boolean isBroken() 查询此屏障是否处于损坏状态。void reset() 将屏障重置为其初始状态。

ConcurentCyclicBarrierDemo1.java 没有Runnable任务的构造方法

package import javaimport javaimport javaimport java/** * @author sunhf * 2015-03-27 * */public class ConcurentCyclicBarrierDemo1{public static void main(String[] args){ExecutorService service = Executors.newCachedThreadPool();final CyclicBarrier cyclicBarrier = new CyclicBarrier(3);for (int i = 0; i < 3; i++){Runnable runnable = new Runnable(){@Overridepublic void run(){try{Thread.sleep((long) (Math.random() * 10000));System.out.println(“线程 ” + Thread.currentThread().getName() + “即将到达关卡(屏障点) 1,当前已经有” + cyclicBarrier.getNumberWaiting() + “个已经到达,正在等候….”);cyclicBarrier.await();Thread.sleep((long) (Math.random() * 10000));System.out.println(“线程 ” + Thread.currentThread().getName() + “即将到达关卡(屏障点) 2,当前已经有” + cyclicBarrier.getNumberWaiting() + “个已经到达,正在等候….”);cyclicBarrier.await();Thread.sleep((long) (Math.random() * 10000));System.out.println(“线程 ” + Thread.currentThread().getName() + “即将到达关卡(屏障点) 3,当前已经有” + cyclicBarrier.getNumberWaiting() + “个已经到达,正在等候….”);cyclicBarrier.await();} catch (InterruptedException e){e.printStackTrace();} catch (BrokenBarrierException e){e.printStackTrace();}}};service.execute(runnable);}service.shutdown();}}

执行结果:

线程 pool即将到达关卡(屏障点) 1,当前已经有0个已经到达,正在等候….线程 pool即将到达关卡(屏障点) 1,当前已经有1个已经到达,正在等候….线程 pool即将到达关卡(屏障点) 1,当前已经有2个已经到达,正在等候….线程 pool即将到达关卡(屏障点) 2,当前已经有0个已经到达,正在等候….线程 pool即将到达关卡(屏障点) 2,当前已经有1个已经到达,正在等候….线程 pool即将到达关卡(屏障点) 2,当前已经有2个已经到达,正在等候….线程 pool即将到达关卡(屏障点) 3,当前已经有0个已经到达,正在等候….线程 pool即将到达关卡(屏障点) 3,当前已经有1个已经到达,正在等候….线程 pool即将到达关卡(屏障点) 3,当前已经有2个已经到达,正在等候….

ConcurentCyclicBarrierDemo2.java 带Runnable任务的构造方法

package import javaimport javaimport javaimport java/** * @author sunhf * 2015-03-27 * */public class ConcurentCyclicBarrierDemo2{public static void main(String[] args){ExecutorService service = Executors.newCachedThreadPool();final CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable(){@Overridepublic void run(){System.out.println(“到我这啦吧!!! 哈哈 可让我逮住你了!!! 你是:” + Thread.currentThread().getName());}});for (int i = 0; i < 3; i++){Runnable runnable = new Runnable(){@Overridepublic void run(){try{Thread.sleep((long) (Math.random() * 10000));System.out.println(“线程” + Thread.currentThread().getName() + “已经到达关卡(屏障点)1,目前正有” + cyclicBarrier.getNumberWaiting() + “个线程正在等待….”);cyclicBarrier.await();Thread.sleep((long) (Math.random() * 10000));System.out.println(“线程” + Thread.currentThread().getName() + “已经到达关卡(屏障点)2,目前正有” + cyclicBarrier.getNumberWaiting() + “个线程正在等待….”);cyclicBarrier.await();Thread.sleep((long) (Math.random() * 10000));System.out.println(“线程” + Thread.currentThread().getName() + “已经到达关卡(屏障点)3,目前正有” + cyclicBarrier.getNumberWaiting() + “个线程正在等待….”);cyclicBarrier.await();} catch (InterruptedException e){e.printStackTrace();} catch (BrokenBarrierException e){e.printStackTrace();}}};service.execute(runnable);}service.shutdown();}}只有经历过地狱般的折磨,才有征服天堂的力量,只有流过血的手指,才能弹出世间的绝唱。

CyclicBarrier介绍及使用说明

相关文章:

你感兴趣的文章:

标签云: