- 1、CyclicBarrier的作用
- 2、CyclicBarrier使用规则
- 3、CyclicBarrier的Demo
- 4、CyclicBarrier原理 (待补充)
- 5、CyclicBarrier的实现 (待补充)
1、CyclicBarrier的作用
CyclicBarrier类也是java提供给我们同步任务的时候使用的,和CountDownLatch有点类似,都是控制任务执行的顺序的,不同的地方在于,CyclicBarrier可以让一个任务在执行的途中发生多次事件,而CountDownLatch却只能发生一次,就是在我们调用countDown方法的时候,这个事件触发以后,便会减少相应的锁存器上面的计数器,而当计数器为0的时候,哪些调用了await的任务便可以执行了,但是CyclicBarrier就不同了,CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞
2、CyclicBarrier的使用规则
CountDownLatch是一个同步的辅助类,允许一个或多个线程,等待其他一组线程完成操作,再继续执行。
CyclicBarrier是一个同步的辅助类,允许一组线程相互之间等待,达到一个共同点,再继续执行。
个人理解:CyclicBarrier:可看成是个障碍,所有的线程必须到齐后才能一起通过这个障碍
场景还原:以前公司组织户外拓展活动,帮助团队建设,其中最重要一个项目就是全体员工(包括女同事,BOSS)在完成其他项目时,到达一个高达四米的高墙没有任何抓点,要求所有人,一个不能少的越过高墙,才能继续进行其他项目。
3、CyclicBarrier的Demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
public class TestCycilcBarrier { static final int FINISH_LINE = 100 ; private List<Horse> mHorses = new ArrayList<Horse>() ; private ExecutorService mExec = Executors.newCachedThreadPool() ; private CyclicBarrier mCyclicBarrier ; public TestCycilcBarrier (int horsesSize, int pause) { mCyclicBarrier = new CyclicBarrier(horsesSize, new Runnable() { @Override public void run() { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < FINISH_LINE; i++) { stringBuilder.append("="); } System.out.println(stringBuilder); for (Horse horse : mHorses) { System.out.println(horse.tracks()); if (horse.getStrides() >= FINISH_LINE) { System.out.println(horse + "won!"); mExec.shutdownNow(); return ; } } try { TimeUnit.MILLISECONDS.sleep(pause); } catch (InterruptedException e) { System.out.println("barrier-action sleep interrupted"); } } }); for (int i = 0; i < horsesSize; i++) { Horse horse = new Horse(mCyclicBarrier); mHorses.add(horse); mExec.execute(horse); } } public static void main(String[] args) { int horsesSize = 10 ; int pause = 200 ; if (args.length > 0) { Integer temp = new Integer(args[0]); horsesSize = temp > 0 ? temp : horsesSize ; } if (args.length > 1) { Integer temp = new Integer(args[1]); pause = temp > 0 ? temp : pause ; } new TestCycilcBarrier(horsesSize, pause); } } class Horse implements Runnable { private static int sCounter = 0 ; private final int ID = sCounter ++ ; private int mStrides = 0 ; private Random mRandom = new Random(47); private static CyclicBarrier sBarrier ; public Horse (CyclicBarrier cyclicBarrier) { this.sBarrier = cyclicBarrier ; } @Override public void run() { try { while (!Thread.interrupted()) { synchronized (this) { mStrides += mRandom.nextInt(5); } sBarrier.await(); } } catch (InterruptedException e) { } catch (BrokenBarrierException e) { throw new RuntimeException(e) ; } } public synchronized int getStrides () { return mStrides ; } @Override public String toString() { return "Horse " + this.ID ; } public String tracks () { StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < getStrides(); i++) { stringBuffer.append("-"); } stringBuffer.append(this.ID); return stringBuffer.toString() ; } }
|
上述Demo运行起来的效果图,如下图所示:

参考文献