java中的同步工具类CountDownLatch
这篇文章主要讲解java中一个比较常用的同步工具类CountDownLatch,不管是在工作还是面试中都比较常见。我们将通过案例来进行讲解分析。
一、定义
CountDownLatch的作用很简单,就是一个或者一组线程在开始执行操作之前,必须要等到其他线程执行完才可以。我们举一个例子来说明,在考试的时候,老师必须要等到所有人交了试卷才可以走。此时老师就相当于等待线程,而学生就好比是执行的线程。
注意:java中还有一个同步工具类叫做CyclicBarrier,他的作用和CountDownLatch类似。同样是等待其他线程都完成了,才可以进行下一步操作,我们再举一个例子,在打王者的时候,在开局前所有人都必须要加载到100%才可以进入。否则所有玩家都相互等待。
我们看一下区别:
CountDownLatch: 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。 CyclicBarrier : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。关键点其实就在于那N个线程(1)CountDownLatch里面N个线程就是学生,学生做完了试卷就可以走了,不用等待其他的学生是否完成(2)CyclicBarrier 里面N个线程就是所有的游戏玩家,一个游戏玩家加载到100%还不可以,必须要等到其他的游戏玩家都加载到100%才可以开局
现在应该理解CountDownLatch的含义了吧,下面我们使用一个代码案例来解释。
二、使用
我们使用学生考试的案例来进行演示:

在上面,我们定义了一个CountDownLatch,并设置其值为2。有两个学生使用两个线程来表示,然后依次执行。最后老师线程(main线程)在学生线程都执行完了才可以执行。我们来运行一边看看结果。

现在我们应该能体会到其用法了吧。在上面我们的等待线程时老师(main线程)。
下面我们对这个countDownLatch分析一下。为什么具有上面的特点。
三、原理
在上面我们看到,CountDownLatch主要使用countDown方法进行减1操作,使用await方法进行等到操作。我们进入到源码中看看。本源码基于jdk1.8。特在此说明。
1、countDown原理

英语不好的人看起来真的是一脸懵逼,不过信号上面的英语还都是简单的英语,大致意思是这样的:CountDownLatch里面保存了一个count值,通过减1操作,直到为0时候,等待线程才可以执行。而且通过源码也可以看到这个countDown方法其实是通过sync调用releaseShared(1)来完成的。
OK。到了这一步我们可能会纳闷,sync是个什么鬼,releaseShared方法又是如何实现的。我们不妨接着看源码,在CountDownLatch的开头我们找到了答案,原来这个sync在这里定义了。

在这里我们发现继承了AbstractQueuedSynchronizer(AQS)。AQS的其中一个作用就是维护线程状态和获取释放锁。在这里也就是说CountDownLatch使用AQS机制维护锁状态。而releaseShared(1)方法就是释放了一个共享锁。
现在理解了吧,底层使用AQS机制调用releaseShared方法释放一个锁资源。那么等待的方法是如何实现的呢?
2、await原理

这俩方法都是让线程等待,第一个没有实现限制,第二个有时间限制,我们一个一个来看。
(1)await()
await()底层主要是acquireSharedInterruptibly方法实现的,继续跟进去看看。

这里面有两个if语句,首先第一个判断是否被中断,如果被中断了,那就抛出中断异常。然后判断当前是否还有线程未执行,如果有那就,那就执行doAcquireSharedInterruptibly方法继续等待。

上面函数的意思已经在注释里面了,下面我们就来看看这个doAcquireSharedInterruptibly是如何实现的。

这块的代码比较长,不过大致意思我可以描述一下,他会用一个一个的节点将线程串起来 等达到条件后再一个一个的唤醒。核心就是第三行的addWaiter函数。我们可以再跟进去看看吧。

你会发现这里面也使用了CAS机制。而且就是使用链表穿起来的。
(2) await(long timeout, TimeUnit unit)
这个方法的意思是等待指定的时间,如果还有线程没执行完,那就接着执行。就好比考完试了,还有同学没交试卷,此时因为到时间了。不管三七二十一也不管剩下的同学是否提交,直接就走了。其底层是通过Sync的tryAcquireSharedNanos方法实现的,我们接着进入到源码中看看。

在这里皮球又一次被踢走了,真正实现的其实就是doAcquireSharedNanos方法,tryAcquireShared方法主要是判断是否当前满足wait的条件。我们接着看。

上面的代码看似长,最核心的就是for循环里面的,最主要的意思就是如果当前还有线程未执行而且过了超时时间,那就直接执行等待线程就好了,不再等了。也就是我在指定的时间内你没执行完我等着你,要是超了这个时间点我就不管了。
对于CountDownLatch来说原理主要还是通过源码来认识。不过CountDownLatch看起来虽然很好用,也有很多不足之处,比如说CountDownLatch是一次性的 , 计数器的值只能在构造方法中初始化一次 , 之后没有任何机制再次对其设置值,当CountDownLatch使用完毕后 , 它不能再次被使用。
OK。对其介绍就先到这里吧。
相关文章:
java中的同步工具类CountDownLatch
这篇文章主要讲解java中一个比较常用的同步工具类CountDownLatch,不管是在工作还是面试中都比较常见。我们将通过案例来进行讲解分析。 一、定义 CountDownLatch的作用很简单,就是一个或者一组线程在开始执行操作之前,必须要等到其他线程执…...
路由器和交换机的区别
交换机和路由器的区别 交换机实现局域网内点对点通信,路由器实现收集发散,相当于一个猎头实现的中介的功能 路由器属于网络层,可以处理TCP/IP协议,通过IP地址寻址;交换机属于中继层,通过MAC地址寻址(列表)…...
FreeRTOS(动态内存管理)
资料来源于硬件家园:资料汇总 - FreeRTOS实时操作系统课程(多任务管理) 目录 一、动态内存管理介绍 1、heap_1 2、heap_2 3、heap_3 4、heap_4 5、heap_5 二、动态内存总结与应用 1、heap_1 2、heap_4 3、heap_5 三、内存管理编程测试 1、heap_4 2、h…...
IntelliJ IDEA(简称Idea) 基本常用设置及Maven部署---详细介绍
一,Idea是什么? 前言: 众所周知,现在有许多编译工具,如eclipse,pathon, 今天所要学的Idea编译工具 Idea是JetBrains公司开发的一款强大的集成开发环境(IDE),主要用于Java…...
【LeetCode每日一题】——128.最长连续序列
文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 哈希表 二【题目难度】 中等 三【题目编号】 128.最长连续序列 四【题目描述】 给定一个未…...
Redis_缓存1_缓存类型
14.redis缓存 14.1简介 穿透型缓存: 缓存与后端数据交互在一起,对服务端的调用隐藏细节。如果从缓存中可以读到数据,就直接返回,如果读不到,就到数据库中去读取,从数据库中读到数据,也是先更…...
模拟 枚举
分享牛客算法基础精选题单题目打卡!!! 目录 字符串的展开 多项式输出 机器翻译 : 铺地毯 : [NOIP2016]回文日期 字符串的展开 原题链接 : 字符串的展开 思路 : 模拟 代码 : #include<iostream> #include<cstring> #include<algorithm> using na…...
【实操】2023年npm组件库的创建发布流程
2022年的实践为基础,2023年我再建一个组件库【ZUI】。步骤回顾: 2022年的npm组件包的发布删除教程_npm i ant-design/pro-components 怎么删除_啥咕啦呛的博客-CSDN博客 1.在gitee上创建一个项目,相信你是会的 2.创建初始化项目,看吧&#…...
缓存设计的典型方案
缓存设计的典型方案 在使用缓存系统的时候,还需要考虑缓存设计的问题,重点在于缓存失效时的处理和如何更新缓存。 缓存失效是在使用缓存时不得不面对的问题。在业务开发中,缓存失效时由于找不到整个数据,一般会出于容错考虑&#…...
SQL笔记
最近的工作对SQL的应用程度较高,而且写的sql类型基本没怎么涉及过,把用到的几个关键字记录下。 使用环境:达梦数据库 达梦数据库有个特点,他有一个叫模式的说法,在图形化工具里直接点击创建查询窗口,不用像…...
UHPC的疲劳计算——兼论ModelCode2010的适用性
文章目录 0. 背景1、结论及概述2、MC10对于SN曲线的调整(囊括NC、HPC、UHPC)2.1 疲劳失效曲面的构建2.2 新模型的验证 3、MC10对于疲劳设计强度的调整及其背后的原因4. 结语 0. 背景 今年年初,有一位用UHPC做混凝土塔筒的同行告诉我…...
关于elementui的input的autocomplete的使用
项目中需要实现搜索框搜索时能自动提示可选项的功能,elementui的input组件有已经封装好的el-autocomplete可以使用,但是在使用中发现一些问题,记录一下 基础使用 // html部分 <el-autocompletev-model"name":fetch-suggestion…...
即然利用反射机制可以破坏单例模式,有什么方法避免呢?
私有构造方法中添加防止多次实例化的逻辑:在单例类的私有构造方法中,可以添加逻辑来检查是否已经存在实例,如果存在则抛出异常或返回已有的实例。这样即使通过反射创建了新的实例,也能在构造方法中进行拦截。 使用枚举实现单例&a…...
【IDEA问题】下载不了源代码
引出问题 最近不知道怎么打开 IDEA,本想查看源代码,然后点击下载源码,总是报找不到此对象的源代码。百度找了半天,GPT问了半天还是解决不了,直到遇到了这篇:idea中无法下载源码问题解决,终于得…...
代码随想录第四十八天
代码随想录第四十八天 Leetcode 198. 打家劫舍ILeetcode 213. 打家劫舍 IILeetcode 337. 打家劫舍 III Leetcode 198. 打家劫舍I 题目链接: 打家劫舍I 自己的思路:想不太出来递推公式!!!! 正确思路:这个题主要是看是否偷第下标为…...
书写自动智慧:探索Python文本分类器的开发与应用:支持二分类、多分类、多标签分类、多层级分类和Kmeans聚类
书写自动智慧:探索Python文本分类器的开发与应用:支持二分类、多分类、多标签分类、多层级分类和Kmeans聚类 文本分类器,提供多种文本分类和聚类算法,支持句子和文档级的文本分类任务,支持二分类、多分类、多标签分类…...
前端Webpack面试题
1.说说你对webpack的理解 开发时,我们会使用框架 (React、Vue) ,ES6 模块化语法,Less/Sass 等 CSS 预处理器等语法进行开发,这样的代码要想在浏览器运行必须经过编译成浏览器能识别的 JS、CSS语法才能运行。所以我们需要打包工…...
LabVIEW使用边缘检测技术实现彩色图像隐写术
LabVIEW使用边缘检测技术实现彩色图像隐写术 隐写术是隐藏信息的做法,以隐瞒通信的存在而闻名。该技术涉及在适当的载体(如图像,音频或视频)中插入秘密消息。在这些载体中,数字图像因其在互联网上的广泛使用而受到青睐…...
第一次参加计算机会议报告注意事项以及心得
计算机会议参会报告 注意事项参会前参会中参会后 参会心得 注意事项 接下来的会议注意事项分为:(1)参会前,(2)参会中,(3)参会后 参会前 参会前,一般被邀请…...
TypeScript教程(二)基础语法与基础类型
一、基础语法 TypeScript由以下几个部分组成 1.模块 2.函数 3.变量 4.语句和表达式 5.注释 示例: Runoob.ts 文件代码: const hello : string "Hello World!" console.log(hello) 以上代码首先通过 tsc 命令编译: tsc …...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
