Java并发之CyclicBarria的使用
一.简介
笔者在写CountDownLatch这个类的时候,看到了博客园上的《浅析Java中CountDownLatch用法》这篇博文,为博主扎实的技术功底所折服,对Java多线程方面的只是信手拈来,首先在此感谢博主给了我灵感,让我进一步了解了CountDownLatch的用法,在此请收下小弟的膝盖(如果博主能够看到的化)。借着《浅析Java中CountDownLatch用法》这篇博文,笔者想借着这个例子说一下 CyclicBarria的用法。CyclicBarria中文翻译过来就是"循环栅栏"。
二. CyclicBarria的使用
读者如果读到该文章,请先观看一下 《浅析Java中CountDownLatch用法》这篇文章,笔者只是借助于该博文作者,稍稍作了写修改,用CyclicBarria来实现。代码如下:
public class CyclicBarriaTest2 { private static final int PLAYER_AMOUNT = 5; //五个运动员 private static ExecutorService exe = Executors.newFixedThreadPool(PLAYER_AMOUNT); static class Command implements Runnable { private boolean flag; public Command(boolean flag){ this.flag = flag; } @Override public void run() { if(flag){ System.out.println("比赛开始..."); flag = false; }else{ System.out.println("比赛结束..."); exe.shutdown(); } } } public static void main(String[] args) { /** * 循环栅栏。当cb调用 await()方法的时候,当5个线程全部就绪,就执行 Command实例化的线程, * 当所有线程,执行完毕,后又碰到await()方法,就等5个线程全部执行完毕, 然后再执行Command的实例 * 线程。 */ CyclicBarrier cb = new CyclicBarrier(5, new Command(true)); Player[] plays = new Player[PLAYER_AMOUNT]; for(int i = 0; i < PLAYER_AMOUNT; i++) { plays[i] = new Player(i+1, cb); } for(Player p:plays) { exe.execute(p); //分配线程 } } }
Player类的实现如下:
class Player implements Runnable{ private int num; private CyclicBarrier cb; public Player(int num, CyclicBarrier cb){ this.num = num; this.cb = cb; } @Override public void run() { try { cb.await(); //等待所有线程就绪,执行cb中的线程。 Thread.sleep((long)(Math.random() * 100)); //随机分配时间,即运动员完成时间 System.out.println("Play" + num + " arrived."); cb.await(); //当所有线程执行完毕,再去执行cb中的线程 } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } }