在上一次Java精通并发-CountDownLatch使用场景与示例分析及底层源码解读已经学习了对于CountDownLatch的使用了,回忆一下它的使用场景:
这次准备学习一个跟它很类似的,但是呢使用场景还是有一些区别的,它就是CyclicBarrier,它也是在面试中很容易就会跟CoutDownLatch一起被问的,所以接下来来看一下它的使用场景。
CyclicBarrier使用场景:
先来描述一下它的使用场景:有若干个线程,比如说有五个线程,需要它们都到达了某一个点之后才能开始一起执行,也就是说假如其中只有四个线程到达了这个点,还差一个线程没到达,此时这四个线程都会进入等待状态,直到第五个线程也到达了这个点之后,这五个线程才开始一起进行执行状态,是不是这个场景的描述跟CountDownLatch很类似的,下面用一个简单的示例图来感受一下它们两者的区别:
有一个主线程,多个子线程:
好,这个我们已经非常清楚了,接下来再来感受一下CyclicBarrier的使用场景,其中Barrier有屏障的意思,里面会涉及到屏障的含义:
这里就没有涉及到主线程的角色的,线程都是同等的,其中图中画了一个屏障,其中有三个线程到达了屏障了:
由于还剩一个子线程木有到达屏障,则到达屏障了的线程会陷入等待状态,直到最后一个子线程到达屏障,如下:
此时所有子线程都已经到达屏障之后,此时屏障就会消失:
然后所有的线程全部从屏障中挣脱了,继续往下执行:
所以从图例来看,跟CoutDownLatch的一个最大的区别是,CyclicBarrier是木有主子线程区分的,另外就是当到达屏障点之后是所有线程都开始进行执行状态,那下面来看一下它的官网说明:
具体实现:
在对它有了一定的理论了解之后,接下来使用一下它:
先来理解一下这个构造函数:
那接下来则创建三个线程:
此时的cyclicBarrier还木有使用上,接下来则可以调用一下它了:
好,使用就是这么简单,接下来则看一下运行效果:
而它跟CountDownLatch还有一个非常明显的区别就是,CoutDownLatch如果计数器减为0了则就计数器永远都为0,不可能再增加了,而CyclicBarrier在上面我们读官方说明时就可以知道,它是一个可以循环被使用的:
啥意思?其实意思就是说当它里面的计数器减为0之后,不是屏障被冲破所有线程可以继续执行了嘛,此时屏障的计数器又会恢复之前所定义的,像咱们的这个例子也就是计数器又会变为3,所以它可以继续被重用,那。。这个被重复的机制是适合哪种场景?这里看一下博主的这篇http://www.itboth.com/d/zABfYr/cyclicbarrier-java说明,我觉得还是蛮形象的:
如果这种场景自己手动来实现还是比较麻烦的,但是!!!有了CyclicBarrier可以很轻松的实现,其中也可以看到CyclicBarrier可以循环使用这一特点,下面用代码来模拟一下这种场景:
然后运行一下:
其中效果也差不多,每阶段都会等三个线程到达屏障之后再执行:
其中如果想要做汇总的操作,可以使用到CyclicBarrier的第二个构造参数,如下:
咱们来试一下:
运行:
关注个人公众号,获得实时推送