Java 线程同步三剑客:CountDownLatch、CyclicBarrier 和 Phaser。

之前分享过这三者在性能测试中的应用,以及线程同步类 CyclicBarrier 在性能测试集合点应用的文章,但是文字读起来略微枯燥了一些。

在我初学这块内容的时候也是看到其他人的讲解文章以及自己不断尝试才掌握了三个类的基本使用。后来某一次在搜资料的时候发现了有人将这些内容,画成了流程图的形式,非常好理解。

可能是因为年代久远了,图像线条相对简单,所以我就班门弄斧,使用draw.io重新画了一下。

CountDownLatch

CountDownLatch类位于java.util.concurrent包下,利用它可以实现计数器的功能。比如有一堆任务需要多线程去执行,需要在所有任务执行完之后才能进行下一步这个场景,此时就可以利用CountDownLatch来实现这种功能了。

参考文章:CountDownLatch 类在性能测试中应用

CyclicBarrier

CyclicBarrier也叫同步屏障,在JDK1.5被引入,可以让一组线程达到一个屏障时被阻塞,直到最后一个线程达到屏障时,所以被阻塞的线程才能继续执行。在执行很多个任务,但是这些任务中间某个节点需要等到其他任务都执行到固定的节点才能继续进行,先到达的线程会一直等待所有线程到达这个节点。在性能测试中,经常会遇到N 多个用户同时在线的场景,一般处理起来都是先让这N 多个用户登录,然后保持登录状态,然后去并发请求。这个场景下CyclicBarrier就能完美解决我们的需求。

参考文章:CyclicBarrier 类在性能测试中应用

Phaser

Phaser的功能与CountDownLatchCyclicBarrier有部分重叠,同时提供了更丰富的语义和更灵活的用法。Phaser比较适合这样一种场景,一种任务可以分为多个阶段,现希望多个线程去处理该批任务,对于每个阶段,多个线程可以并发进行,但是希望保证只有前面一个阶段的任务完成之后才能开始后面的任务。这种场景可以使用多个CyclicBarrier来实现,每个CyclicBarrier负责等待一个阶段的任务全部完成。但是使用CyclicBarrier的缺点在于,需要明确知道总共有多少个阶段,同时并行的任务数需要提前预定义好,且无法动态修改。而Phaser可同时解决这两个问题,可以随时在任务过程中增加删除需要等待的个数。

参考文章:Phaser 类在性能测试中应用


FunTester腾讯云年度作者、Boss 直聘签约作者,非著名测试开发 er,欢迎关注。


↙↙↙阅读原文可查看相关链接,并与作者交流