CountDownLatch 和 CyclicBarrier的区别与详解

文章目录

      • 一.CountDownLatch 和 CyclicBarrier的区别
      • 二.详解
      • 总结
      • 用法
        • CountDownLatch 用法
        • CyclicBarrier 用法

一.CountDownLatch 和 CyclicBarrier的区别

  1. CountDownLatch和CyclicBarrier都是线程同步的工具类,都是基于AQS实现的;
  2. CountDownLatch 的计数器是大于或等于线程数的,而CyclicBarrier是一定等于线程数;
  3. CountDownLatch 放行由其他线程控制而CyclicBarrier是由本身来控制的,CountDownLatch允许一个或多个线程一直等待,直到这些线程完成它们的操作,而CyclicBarrier不一样,它往往是当线程到达某状态后,暂停下来等待其他线程,等到所有线程均到达以后,才继续执行,二者的等待主体是不一样的;
  4. CountDownLatch调用await()通常是主线程/调用线程,而CyclicBarrier调用await()是在任务线程调用的;
  5. CountDownLatch 操作的是事件,阻塞足够多的次数即可,不管几个线程;而 CyclicBarrier 侧重点是线程,强调多个线程间互相等待,同时结束;
  6. CountDownLatch 是不可以重置的,所以无法重用;而 CyclicBarrier 则没有这个限制,可以重用

二.详解

CountDownLatch是通过计数器实现,每次完成一个任务后,计数器减一当为0时,CountDownLatch.await()方法的线程就可以恢复执行任务。

CountDownLatch是基于AQS实现的,它的实现机制很简单,当我们在构建CountDownLatch对象时,传入的值其实就会赋值给 AQS 的关键变量state,执行countDown方法时,其实就是利用CAS 将state 减一,执行await方法时,其实就是判断state是否为0,不为0则加入到队列中,将该线程阻塞掉(除了头结点),因为头节点会一直自旋等待state为0,当state为0时,头节点把剩余的在队列中阻塞的节点也一并唤醒。

CyclicBarrier是直接借助ReentrantLock加上Condition 等待唤醒的功能 进而实现的,在构建CyclicBarrier时,传入的值会赋值给CyclicBarrier内部维护count变量,也会赋值给parties变量(这是可以复用的关键),每次调用await时,会将count -1 ,操作count值是直接使用ReentrantLock来保证线程安全性,如果count不为0,则添加则condition队列中,如果count等于0时,则把节点从condition队列添加至AQS的队列中进行全部唤醒,并且将parties的值重新赋值为count的值(实现复用)

总结

CountDownlatch基于AQS实现,会将构造CountDownLatch的入参传递至state,countDown()就是在利用CAS将state减-1,await()实际就是让头节点一直在等待state为0时,释放所有等待的线程
CyclicBarrier则利用ReentrantLock和Condition,自身维护了count和parties变量。每次调用await将count-1,并将线程加入到condition队列上。等到count为0时,则将condition队列的节点移交至AQS队列,并全部释放。

用法

CountDownLatch 用法

从代码层面,CountDownLatch 的用法是:

// 设置10个计数 
CountDownLatch countDownLatch = new CountDownLatch(10); 
// 每次调用即可减1 
countDownLatch.countDown(); 
// 其他线程一直等待减到0后,才继续执行 
countDownLatch.await()

举个栗子:
假设有一个业务场景,我们要求把所有的图片上传到文件服务器,然后将图片的地址URL保存到数据库;
其中上传素材,我们可以使用多线程去上传,都上传完之后,再入库。

publicbooleandealVedoi(List<Vedio>vedioList){//每个线程处理的最大任务数intmaxNum=10;intthreadNums=0;Map<String,String>map=newConcurrentHashMap<String,String>((int)(vedioList.size()/0.75));if(vedioList.size()<maxNum){threadNums=1;}else{//获取当前系统可用的处理器核心数量threadNums=Runtime.getRuntime().availableProcessors()>vedioList.size()/maxNum?vedioList.size()/maxNum:Runtime.getRuntime().availableProcessors();}try{//创建固定线程数处理这批任务ExecutorServiceexecutor=Executors.newFixedThreadPool(threadNums);CountDownLatchcountDownLatch=newCountDownLatch(vedioList.size());Iterator<Vedio>iterator=vedioList.iterator();while(iterator.hasNext()){executor.submit(()->{Vediovedio=iterator.next();Stringurl=store(vedio);map.put(vedio.getName());countDownLatch.countDown();});}countDownLatch.await();//所有素材上传成功后,入库saveDataBase(map);}catch(InterruptedExceptione){e.printStackTrace();}
}

newFixedThreadPool 方法用于创建一个固定大小的线程池,其中参数指定线程池的大小(即线程数量)。

适合的线程池大小取决于你的具体需求和应用场景。以下几点是需要考虑的因素:

  1. 任务的性质: 如果你的任务是 CPU 密集型的(需要大量的计算和处理),那么线程池的大小通常与处理器的核心数相近或略多一些可能是合适的。这样可以充分利用 CPU 资源。如果任务是 I/O 密集型的(例如涉及网络请求或文件操作),则可能需要更多的线程,以充分利用等待 I/O 的时间。
  2. 可用的系统资源: 考虑可用的系统资源,包括 CPU 核心数、内存和其他正在运行的应用程序。如果系统资源有限,将线程池大小保持在合理的范围内,以避免过度消耗资源。
  3. 任务的数量和规模: 考虑任务的数量和规模。如果你预计会有大量的任务需要处理,并且这些任务是短暂的,那么增加线程池的大小可以提高并发处理能力。但是,如果任务的数量较少或任务的执行时间较长,可能不需要太多的线程。
    需要注意的是,如果线程池的大小设置过大,可能会导致资源竞争、上下文切换开销增加,甚至对系统性能产生负面影响。因此,需要根据实际情况进行调整和测试,找到适合你应用程序的线程池大小。
    综合考虑以上因素,你可以根据你的应用需求和性能测试来选择一个合适的线程池大小。通常情况下,线程池大小在 2 到 10 之间是一个常见的范围。根据实际情况进行调整和优化是最佳的做法。

CyclicBarrier 用法

从代码使用角度来说:

// 初始化值为5的栅栏 
CyclicBarrier cyclicBarrier = new CyclicBarrier(5); 
// 每个线程调用 await()
cyclicBarrier.await(); 
// 等到有 5 个线程都执行了 await() 之后,继续执行。 
// 并且 栅栏的 计数器会自动重置为 5 ,可以接着用

然后我们模拟一个场景
在游戏中,选好英雄之后,会等待所有 5 个玩家进度条都到 100% 才开始游戏,我们可以使用 CyclicBarrier 来模拟这个场景

publicclassCyclicBarrierTest{privatefinalstaticExecutorServiceEXECUTOR_SERVICE=Executors.newFixedThreadPool(5);privatefinalstaticCyclicBarrierBARRIER=newCyclicBarrier(10);publicstaticvoidmain(String[]args){for(inti=0;i<5;i++){finalStringname="玩家"+i;EXECUTOR_SERVICE.execute(newRunnable(){@Overridepublicvoidrun(){try{Thread.sleep(2000);System.out.println(name+"已准备,等待其他玩家准备...");BARRIER.await();Thread.sleep(1000);System.out.println(name+"已加入游戏");}catch(InterruptedExceptione){System.out.println(name+"离开游戏");}catch(BrokenBarrierExceptione){System.out.println(name+"离开游戏");}}});}EXECUTOR_SERVICE.shutdown();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/53572.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA项目实践——VUE介绍与案例分析

系列文章目录 IDEA项目实践——JavaWeb简介以及Servlet编程实战 IDEA项目实践——Spring集成mybatis、spring当中的事务 IDEA项目实践——Spring当中的切面AOP IDEWA项目实践——mybatis的一些基本原理以及案例 IDEA项目实践——Spring框架简介&#xff0c;以及IOC注解 I…

如何开发一款唯一艺术平台 区块链 /数字藏品

艺术作品是人类文化的瑰宝&#xff0c;而艺术平台则是连接艺术家与观众的桥梁。如何开发一款独一无二的艺术平台&#xff0c;既要满足专业艺术作品展示的要求&#xff0c;又要提供深度思考的空间&#xff0c;这是我们所面临的挑战。本文将从专业性、思考深度和逻辑性等多个方面…

2023年高教社杯数学建模思路 - 复盘:光照强度计算的优化模型

文章目录 0 赛题思路1 问题要求2 假设约定3 符号约定4 建立模型5 模型求解6 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 问题要求 现在已知一个教室长为15米&#xff0c;宽为12米&…

ELK高级搜索(二)

文章目录 7&#xff0e;Java api 文档管理7.1 es技术特点7.2 获取数据7.3 文档查询7.4 文档新增7.5 文档修改7.6 文档删除7.7 文档bulk 8&#xff0e;图解es内部机制8.1 es分布式基础8.2 分片shard、副本replica8.3 单node环境创建index8.4 多node环境replica shard8.5 横向扩容…

strstr函数

目录 函数介绍&#xff1a; 函数分析&#xff1a; ​使用案例&#xff1a; 函数介绍&#xff1a; 返回指向 str1 中第一次出现的 str2 的指针&#xff0c;如果 str2 不是 str1 的一部分&#xff0c;则返回一个空指针。 匹配过程不包括终止空字符&#xff0c;但它到此为止。 …

【Cortex-M3权威指南】学习笔记2 - 指令集

目录 指令集汇编语言基础UAL 近距离检视指令数据传输数据处理子程呼叫与无条件跳转指令标志位与条件转移指令隔离指令饱和运算 CM3 中新引入指令MRS\MSRIF-THENCBZ/CBNZSDIV/UDIVREV RBITSXTBTBB,TBH 指令集 汇编语言基础 一条简单的汇编指令格式&#xff08;注释使用一个分号…

界面组件DevExpress Reporting——增强的SQL和实体框架数据源引入

DevExpress Reporting是.NET Framework下功能完善的报表平台&#xff0c;它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集&#xff0c;包括数据透视表、图表&#xff0c;因此您可以构建无与伦比、信息清晰的报表。 本文总结了v23.1中针对DevExpress报表和BI Das…

远程调试环境配置

利用vscode的插件把远程连接调试php转化为本地调试php&#xff0c;通讯从php xdebug通讯变成vscode通讯 1.在vscode中安装插件 2.安装对应PHP版本的xdebug xdebug版本兼容参考https://xdebug.org/docs/compat#versions xdebug安装教程1https://blog.csdn.net/song634/article/…

核辐射对生物的影响

目录 1.什么是核辐射 2.核辐射的危害 3.核辐射对环境造成的影响 4.核辐射的影响会持续多长时间 1.什么是核辐射 核辐射是指自然界或人工产生的高能粒子或电磁波的放射性能量。当原子核不稳定时&#xff0c;会发生放射性衰变&#xff0c;释放出核辐射。 核辐射主要分为三种类…

免费图床配置:PicGo + Github + jsDelivr

免费图床配置&#xff1a;PicGo Github jsDelivr 前言PicGo Github配置过程jsdelivr加速踩坑注意事项参考资料 觉得文章有收获&#xff0c;欢迎关注公众号鼓励一下作者呀~ 在学习的过程中&#xff0c;也搜集了一些量化、技术的视频及书籍资源&#xff0c;欢迎大家关注公众号…

秒杀系统的业务流程以及优化方案(实现异步秒杀)

先看基本的业务流程 那么我们可以看到整个流程都是一个线程来完成的&#xff0c;这样的话耗时还是很长的&#xff0c;那么可不可以采用多线程去实现呢&#xff1f; 首先我们要思考怎么对业务进行拆分&#xff0c;可以想象一个我们去饭店点餐&#xff0c;会有前台接待&#xff…

python高频面试题

在D盘根目录下创建一个文本文件test.txt&#xff0c;并向其中写入字符串hello world # 方法1: file_test open(./output/a.txt,w,encodingutf8) file_test.write(hello world) file_test.close()# 方法2: 该方式会在不需要使用该文件的时候自动关闭, 不需要手动close关闭资源…

Kafka面试

文章内容转自: 华仔聊技术(Kafka 面试连环炮) 目录 一.初级 1.Kafka核心组件图 2.在 Kafka 中 Zookeeper 作用是什么? 3.生产者有哪些发消息的模式? 4.Kafka 如何合理设置分区数,越多越好吗? Kafka 如何合理设置分区数 分区设置越多越好吗? 5.如何保证 Kafka 中的…

【后端】Core框架版本和发布时间以及.net 6.0启动文件的结构

2023年&#xff0c;第35周&#xff0c;第1篇文章。给自己一个目标&#xff0c;然后坚持总会有收货&#xff0c;不信你试试&#xff01; .NET Core 是一个跨平台的开源框架&#xff0c;用于构建现代化的应用程序。它在不同版本中有一些重要的区别和发布时间 目录 一、Core版本和…

爬虫:绕过5秒盾Cloudflare和DDoS-GUARD

本文章仅供技术研究参考&#xff0c;勿做它用&#xff01; 5秒盾的特点 <title>Just a moment...</title> 返回的页面中不是目标数据&#xff0c;而是包含上面的代码&#xff1a;Just a moment... 或者第一次打开网页的时候&#xff1a; 这几个特征就是被Cloud…

【QT】绘制旋转等待

很高兴在雪易的CSDN遇见你 ,给你糖糖 欢迎大家加入雪易社区-CSDN社区云 前言 程序中经常会遇到耗时的操作,需要提供等待的窗口,防止用户多次点击造成卡顿等问题。本文分享旋转等待技术,希望对各位小伙伴有所帮助!结果如下:

Unity 之transform.LookAt() 调整一个物体的旋转,使其朝向指定的位置

文章目录 总的介绍补充&#xff08;用于摄像机跟随的场景&#xff09; 总的介绍 transform.LookAt 是 Unity 引擎中 Transform 组件的一个方法&#xff0c;用于调整一个物体的旋转&#xff0c;使其朝向指定的位置。通常情况下&#xff0c;它被用来使一个物体&#xff08;如摄像…

一篇文章搞定《玩转WebView》

一篇文章搞定《玩转WebView》 前言WebView的常见方法WebView的状态相关方法WebView的前进和后退WebView的缓存 WebView常用的子类WebSettings类WebViewClient类WebChromeClient类 WebView和JavaScript的交互JS调用Android通过 WebView 的addJavascriptInterface()进行对象映射通…

盘点 2023 十大免费开源 WAF

WAF 是 Web Application Firewall 的缩写&#xff0c;也被称为 Web 应用防火墙。区别于传统防火墙&#xff0c;WAF 工作在应用层&#xff0c;对基于 HTTP/HTTPS 协议的 Web 系统有着更好的防护效果&#xff0c;使其免于受到黑客的攻击。 近几年经济增速开始放缓&#xff0c;科…

ajax和fetch的区别

ajax 和 fetch的相同点和区别是什么&#xff1f; 以前我们都用ajax去做请求&#xff0c; 但是原生的ajax不好用&#xff0c;我们会用$.ajax或者axios插件去请求&#xff0c;他们都是ajax的封装 最近出来个fetch是什么&#xff1f; 问到这里的时候&#xff0c;你就已经入坑了&am…