CountDownLatch与CyclicBarrier使用与理解
CountDownLatch
我之前遇到过这么一个需求:“客户端同时下载视频、音频和大量试题压缩包”。我让线程池分配三个线程同时开启下载三类数据,等到它们都下载完成时再进行数据整合操作。问题来了,如何在没有线程安全问题情况下监听到这三个线程已经都执行完毕了呢?此时CountDownLatch类就是最佳选择。
CountDownLatch是一个同步的辅助工具类,允许一个或多个线程,等待其它一组线程完成操作,再继续执行。它其实就是一个倒计时同步锁。
class DownloadVideo implements Runnable{private CountDownLatch latch;public DownloadVideo(CountDownLatch latch){this.latch = latch;}@Overridepublic void run() {try {//启动下载视频......latch.countDown();}catch (Exception ex){ex.printStackTrace();}}}class DownloadAudio implements Runnable{private CountDownLatch latch;public DownloadVideo(CountDownLatch latch){this.latch = latch;}@Overridepublic void run() {try {//下载音频......latch.countDown();}catch (Exception ex){ex.printStackTrace();}}}class DownloadTestZip implements Runnable{private CountDownLatch latch;public DownloadVideo(CountDownLatch latch){this.latch = latch;}@Overridepublic void run() {try {//下载音频......latch.countDown();}catch (Exception ex){ex.printStackTrace();}}}class IntegrationData implements Runnable{@Overridepublic void run() {//创建CountDownLatch计数器,计数次数:3CountDownLatch latch = new CountDownLatch(3);Executor executor = Executors.newFixedThreadPool(3);executor.execute(new DownloadVideo(latch));executor.execute(new DownloadAudio(latch));executor.execute(new DownloadTestZip(latch));// 3个线程countDown()都执行之后才会释放当前线程,程序才能继续往后执行latch.await();//执行数据整合}}
CountDownLatch怎么理解呢?
CountDownLatch是在线程安全的条件下计数,没执行一次countDown方法计数器就会递减1,直到计数器为0,await方法以后的代码才会被执行。
使用情景举例:
玩LOL时,平台要求同组每位英雄都加载完成后,所有英雄才可以进入游戏环节。
CyclicBarrier
还是上面的项目实例,后来因为CountDownLatch我发现了CyclicBarrier这个类,对于这个项目实例CyclicBarrier也可以实现。
class DownloadVideo implements Runnable{private CyclicBarrier cb;public DownloadVideo(CyclicBarrier cb){this.cb = cb;}@Overridepublic void run() {try {//启动下载视频......cb.await();}catch (Exception ex){ex.printStackTrace();}}}class DownloadAudio implements Runnable{private CyclicBarrier cb;public DownloadAudio(CyclicBarrier cb){this.cb = cb;}@Overridepublic void run() {try {//下载音频......cb.await();}catch (Exception ex){ex.printStackTrace();}}}class DownloadTestZip implements Runnable{private CyclicBarrier cb;public DownloadTestZip(CyclicBarrier cb){this.cb = cb;}@Overridepublic void run() {try {//下载音频......cb.await();}catch (Exception ex){ex.printStackTrace();}}}class IntegrationData implements Runnable{@Overridepublic void run() {//整合数据}}CyclicBarrier cb = new CyclicBarrier(3,new IntegrationData());//开启线程执行下载视频、下载音频和下载试题压缩包任务Executor executor = Executors.newFixedThreadPool(3);executor.execute(new DownloadVideo(cb));executor.execute(new DownloadAudio(cb));executor.execute(new DownloadTestZip(cb));
当下载视频、下载音频和下载试题压缩包线程都执行到await方法时,此时数据整合线程才会执行。
CountDownLatch与CyclicBarrier的区别
CountDownLatch:线程安全,内部维护一计数器,每执行一次downCount方法,计数器减一,await方法会阻塞线程执行,直到计数器为0时,才会继续await方法以后的代码。
CyclicBarrier:线程安全,内部维护一计数器,每执行一次await方法,计数器减一,await方法会阻塞当前所在线程,直到计数器为0时,会唤醒同一个Condition上所有线程,继续执行。new CyclicBarrier(3,new IntegrationData()),当使用两个参数的构造时,需要传一个线程,此时,计数器被减至0时,会执行这个线程,当线程执行完毕之后,才会唤醒同一个Condition上所有线程继续执行。
//CyclicBarrier的dowait方法,await方法中调用了dowait方法。关键代码就在这个方法中。private int dowait(boolean timed, long nanos)//线程同步锁final ReentrantLock lock = this.lock;lock.lock();try {final Generation g = generation;//计数器减一int index = --count;if (index == 0) { // trippedboolean ranAction = false;try {final Runnable command = barrierCommand;//如果有两个参数的构造传了线程,那么此时就执行这个线程。if (command != null)command.run();ranAction = true;//生命代切换nextGeneration();return 0;} finally {if (!ranAction)breakBarrier();}}......//以上执行完毕for (;;) {try {//唤醒Condition上所有线程if (!timed)trip.await();//唤醒超时时间else if (nanos > 0L)nanos = trip.awaitNanos(nanos);} catch (InterruptedException ie) {if (g == generation && ! g.broken) {breakBarrier();throw ie;} else { Thread.currentThread().interrupt();}}if (g != generation)return index;if (timed && nanos <= 0L) {breakBarrier();throw new TimeoutException();}}} finally {lock.unlock();}}
CountDownLatch与CyclicBarrier使用与理解相关推荐
- Java的CountDownLatch和CyclicBarrier的理解和区别
CountDownLatch和CyclicBarrier的功能看起来很相似,不易区分,有一种谜之的神秘.本文将通过通俗的例子并结合代码讲解两者的使用方法和区别. CountDownLatch和Cycl ...
- 秒懂 CountDownLatch 与 CyclicBarrier 使用场景
作者 | pony-zi 来源 | https://blog.csdn.net/zzg1229059735/article/details/61191679 相信每个想深入了解多线程开发的Java开发 ...
- Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析
1.简介 在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步 ...
- Thread.join(), CountDownLatch、CyclicBarrier和 Semaphore区别,联系及应用
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法, 由于 ...
- CountDownLatch和CyclicBarrier的区别
[CountDownLatch.CyclicBarrier和Semaphore] http://www.cnblogs.com/dolphin0520/p/3920397.html [CountDow ...
- 【多线程】CountDownLatch 和 CyclicBarrier:如何让多线程步调一致?
假设现在有一个对账系统,需要优化一下.它的基本业务是用户通过在线商城下单,然后生成电子订单,保存在订单库:之后物流会生成派送单给用户发货,派送单保存在派送单库.为了防止漏派送或重复派送,对账系统每天会 ...
- CountDownLatch与CyclicBarrier
文章目录 倒计时器CountDownLatch 循环栅栏CyclicBarrier CountDownLatch与CyclicBarrier的比较 倒计时器CountDownLatch 在多线程协作完 ...
- 并发工具之CountDownLatch与CyclicBarrier
文章目录 倒计时器CountDownLatch 循环栅栏CyclicBarrier CountDownLatch与CyclicBarrier的比较 倒计时器CountDownLatch 在多线程协作完 ...
- Java并发编程之CountDownLatch、CyclicBarrier和Semaphore
前言 本文为对CountDownLatch.CyclicBarrier.Semaphore的整理使用 CountDownLatch CountDownLatch类位于java.util.concurr ...
最新文章
- i基准指令集 mips_mips addiu
- yolov3为什么对大目标检测不好_基于改进Yolov3的目标检测的研究
- syslog简介——系统日志写入API
- 日光能和电池两用计算机,计算机类专业竞赛模拟试题(doc 7页)全面优秀版优秀版...
- HibernateBaseDAO
- 一些非常有用的备忘录文档
- 周末随笔 | 问好一个问题,有的放矢
- 在Excel中实现下拉列表选择录入
- vue读取终端硬件信息_自助服务终端机主要特点及规格
- linux服务器配置jdk1.8
- 机器学习算法在用户行为检测(UBA)领域的应用
- 排列算法 C++实现
- MySQL 6.子查询
- 文本文档怎么转换为html文件,win10系统下如何将文本文档转换为网页
- AG螺纹的螺套安装后反复脱出,怎么办?
- 被退回的劳务派遣工需要支付补偿金吗?
- GCN与GAT之间的重要联系和区别
- 计算机千分之一符号,千分之一,万分之一的符号在
- 如何将AD类型的封装导成Allegro库中的封装
- 趣味算法:国王和100个囚犯
热门文章
- 无责任转帖 有谁知道复旦这事是真的吗?
- 微型计算机的外存储器 现在普遍采用什么,微型计算机中的外存储器,现在普遍采用___________。...
- matlab中round函数的使用方法(四舍五入)
- 全媒体运营师胡耀文教你:社区运营的7条运营思路
- 三星android图片,三星首款安卓相机GALAXY Camera高清图赏
- python 毕业设计 源码 博客_blogs: 仅供学习参考使用,Python Django毕业设计——个人博客系统...
- 中国式家长游戏制作人php要学,当“中国式家长”成为游戏,果然火了!
- win10 关闭默认共享--还有一些不足之处
- 查看电脑系统(系统型号、显卡型号、声卡型号)等等
- 实战|用Python爬取《云南虫谷》3.6万条评论,并做数据统计可视化展示分析,好看!