CountdownLatch 和 CycliBarriar 有什么区别?
一位工作5年的小伙伴面试的时候,被问到这样一个问题,说,CountdownLatch 和 CycliBarriar 有什么区别?这个对于很多人都会比较陌生,但是接触过并发编程的小伙伴来说还是比较简单的。
今天呢,我给大家分享一下我对这个问题的理解。
1、CountdownLatch
ENTER TITLE
先来看CountDownLatch,它是一个组合词。CountDown 的意思是 倒计时,Latch 的意思是 门闩 ,也被翻译成发令枪。在JDK 注释中是这样的:
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
翻译过来就是说,让一个或多个线程持续等待,直到其他多线程执行的一组操作全部完成以后,这些等待的线程才会继续执行。
就好比是,有多位选手参加一场百米赛跑,裁判员需要等待全部选手就绪,并且在同一起跑线上。然后,裁判会发出号令:“各就位,预备跑”,随着发令枪响,所有选手才能全部起跑。在这个场景中,各位参赛选手就是线程,而裁判就是CountDownLatch。
我们在实际开发中,有以下两个使用场景可以用CountDownLatch来实现:
ENTER TITLE
1)让单个线程等待多个线程的场景。
比如,一个服务需要从多个远程接口获取数据,我们可以创建多个线程来分别调用远程接口,等待所有远程接口都获得返回数据之后,主服务线程再往下继续执行。像并发计算,结果汇总等等。
2)让多个线程等待的场景。
比如,模拟秒杀场景,让一组线程同时等待,同时恢复执行,实现最大程度的并行性。
ENTER TITLE
需要注意的是,当高并发请求时,Countdownlatch的await方法有可能会引起死锁。
如果线程池中线程的数量较少,在高并发时会出现多个请求占用了全部的线程,但是每个请求又需要await()其他线程,被等待的线程拿不到线程资源无法执行,导致多个请求同时进入线程阻塞,最后形成死锁。
当然,我们可以使用自定义线程池来扩大线程数量,并且建立线程池拒绝机制来解决死锁问题。
2、CyclicBarrier
ENTER TITLE
再来看 CyclicBarrier [ˈsaɪklɪk] [ˈbæriə],它也是一个组合词。其中Cyclic 的意思是 循环 ,Barrier 的意思是 屏障 ,又被翻译成栅栏。在JDK 注释中是这样描述的:
A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.
CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other.
The barrier is called cyclic because it can be re-used after the waiting threads are released.
ENTER TITLE
翻译过来总结为以下三点:
1)CyclicBarrier 是一个同步辅助类,它允许一组线程相互等待直到所有线程都到达一个公共的屏障点。
2)在程序中有固定数量的线程,这些线程有时候必须等待彼此,这种情况下,使用 CyclicBarrier 很有帮助。
3)这个屏障之所以用循环修饰,是因为在所有的线程释放彼此之后,这个屏障可以重复使用。
ENTER TITLE
从字面上理解的话,它的功能和CountdownLatch非常类似,也是等待所有参加比赛的选手全部就绪以后,才能开始起跑。它是另外一种多线程并发控制工具,和CountdownLatch不同的是,CyclicBarrier可以重复使用。
我们在实际开发中,CyclicBarrier可以用于多线程计算数据,最后合并计算结果的应用场景。
比如,需要计算N组人一年的平均工资,每组需要多个线程并行计算,计算完一组,再开始下一组,这样就需要多轮并行计算。这个场景下,CyclicBarrier 比 CountDownLatch 更适合。
3、两者区别
ENTER TITLE
最后,总结一下CountDownLatch和CyclicBarrier的区别,从以下四个方面来分析:
1、CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。
2、CyclicBarrier能处理更为复杂的业务场景,比如计算发生错误,可以结束阻塞,重置计数器,重新执行程序
3、CyclicBarrier提供getNumberWaiting()方法,可以获得CyclicBarrier阻塞的线程数量,还提供isBroken()方法,可以判断阻塞的线程是否被中断,等等。
4、CountDownLatch会阻塞主线程,CyclicBarrier不会阻塞主线程,只会阻塞子线程。
好了,以上就是我对CountdownLatch 和 CycliBarriar的理解。
我是被编程耽误的文艺Tom,如果我的分享对你有帮助,请动动手指分享给更多的人。
相关文章
- Java中 super与 this 关键字的作用
- Java中final关键字(Java)
- Java中多态到底怎么用和怎么实现(希望达到最简单的理解)
- IP地址简单介绍+查看本机IP地址-命令
- 迭代器和增强for的使用
- 使用Java中Collections工具类和Comparator比较器使用
- MIME 是什么以及对于文件类型
- 大数据Kudu(八):Kudu与Impala整合
- YAML的基本语法(SpringBoot官方建议的配置文件)
- Spring使用自带的DataSourceTransactionManager声明式事务(xml)模板
- SpringMVC自定义类型转换器(日期格式)模板
- SpringMVC请求参数乱码问题
- SpringMVC基本环境搭建(配置文件模板模板)
- 大数据Kudu(九):Spark操作Kudu
- SpringMVC 文件上传简单模板
- SpringMVC拦截器的简单模板
- Maven的SSM依赖导入基本模板
- SpringMVC自定义异常处理器简单模板
- Mybatis实现分页-分页类的模板(最基础的模板)
- SSM 整合 Shiro 简单应用