当前位置: 首页 > article >正文

详解CountDownlatch

引言

CountDownLatch 是 Java 并发包 java.util.concurrent 中的一个同步工具类,由著名的并发编程大师 Doug Lea 所开发。它允许一个或多个线程等待其他线程完成操作后再继续执行,其核心思想是通过一个计数器,对计数器进行调度来实现

原理

CountDownLatch 初始化时会设置一个计数器的值,该值表示需要等待完成的操作数量。每当一个线程完成了自己的任务后,会调用 countDown() 方法将计数器减 1。当计数器的值变为 0 时,意味着所有需要等待的操作都已完成,此时在 await() 方法上等待的线程将被唤醒,继续执行后续操作。

源码分析

内部类

private final Sync sync;private static final class Sync extends AbstractQueuedSynchronizer {private static final long serialVersionUID = 4982264981922014374L;Sync(int count) {setState(count);}int getCount() {return getState();}protected int tryAcquireShared(int acquires) {return (getState() == 0) ? 1 : -1;}protected boolean tryReleaseShared(int releases) {// Decrement count; signal when transition to zerofor (;;) {int c = getState();if (c == 0)return false;int nextc = c-1;if (compareAndSetState(c, nextc))return nextc == 0;}}
}
  • sync:CountDownLatch 内部使用 Sync 类的实例,Sync 继自 AbstractQueuedSynchronizer(AQS),借助 AQS 的状态(state)来表示计数器的值。
  • Sync 类:
    • 构造函数 Sync(int count):在创建 Sync 实例时,会调用 setState(count) 方法将 AQS 的状态初始化为传入的计数器值。
    • getCount() 方法:返回 AQS 的当前状态,即计数器的当前值。
    • tryAcquireShared(int acquires) 方法:用于尝试以共享模式获取锁。当计数器值为 0 时返回 1,表示可以获取锁;否则返回 -1,表示无法获取锁。
    • tryReleaseShared(int releases) 方法:用于尝试以共享模式释放锁。使用 for(;;) 无限循环结合 compareAndSetState 方法(CAS 操作)来安全地将计数器减 1。当计数器减为 0 时返回 true,表示释放成功且可以唤醒等待线程;否则返回 false。

结合源码我们一般是主线程设计为等待线程,线程池去完成计数器的增减

内部方法

await()

public void await() throws InterruptedException {sync.acquireSharedInterruptibly(1);
}
  • await() 方法会调用 sync 的 acquireSharedInterruptibly(1) 方法,该方法是 AQS 提供的以共享模式获取锁的可中断方法。其具体逻辑为:
    • 检查当前线程是否被中断,若被中断则抛出 InterruptedException 异常。

    • 调用 tryAcquireShared 方法尝试获取锁,若计数器为 0 则获取成功,线程继续执行;否则将当前线程放入等待队列并阻塞。

await(long timeout, TimeUnit unit) 

public boolean await(long timeout, TimeUnit unit)throws InterruptedException {return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}

该方法允许线程等待指定的时间。调用 sync 的 tryAcquireSharedNanos(1, unit.toNanos(timeout)) 方法,在指定时间内尝试以共享模式获取锁。若在超时时间内计数器变为 0 则返回 true;若超时则返回 false。

countDown() 

countDown() 方法调用 sync 的 releaseShared(1) 方法,以共享模式释放锁。该方法会调用 tryReleaseShared 方法尝试将计数器减 1,若减为 0 则唤醒所有在等待队列中的线程。

实战

下面是多线程实战CountDownlatch,依旧是主线程等待,在循环中创建线程调用await方法

import java.util.concurrent.CountDownLatch;public class CountDownLatchExample {public static void main(String[] args) throws InterruptedException {// 创建一个 CountDownLatch 实例,计数器初始值为 3CountDownLatch latch = new CountDownLatch(3);// 创建并启动三个工作线程for (int i = 0; i < 3; i++) {final int workerId = i;new Thread(() -> {try {System.out.println("Worker " + workerId + " is working.");// 模拟工作Thread.sleep((long) (Math.random() * 1000));System.out.println("Worker " + workerId + " has finished.");} catch (InterruptedException e) {e.printStackTrace();} finally {// 工作完成,计数器减 1latch.countDown();}}).start();}// 主线程等待所有工作线程完成System.out.println("Main thread is waiting for workers to finish.");latch.await();System.out.println("All workers have finished. Main thread can continue.");}
}

相关文章:

详解CountDownlatch

引言 CountDownLatch 是 Java 并发包 java.util.concurrent 中的一个同步工具类&#xff0c;由著名的并发编程大师 Doug Lea 所开发。它允许一个或多个线程等待其他线程完成操作后再继续执行&#xff0c;其核心思想是通过一个计数器&#xff0c;对计数器进行调度来实现 原理 …...

STM32外设SPI FLASH应用实例

STM32外设SPI FLASH应用实例 1. 前言1.1 硬件准备1.2 软件准备 2. 硬件连接3. 软件实现3.1 SPI 初始化3.2 QW128 SPI FLASH 驱动3.3 乒乓存储实现 4. 测试与验证4.1 数据备份测试4.2 数据恢复测试 5 实例5.1 参数结构体定义5.2 存储参数到 SPI FLASH5.3 从 SPI FLASH 读取参数5…...

【Excel笔记_6】条件格式和自定义格式设置表中数值超过100保留1位,超过1000保留0位,低于100为默认

方法一&#xff1a;自定义格式 选中需要设置格式的单元格区域。右键选择设置单元格格式&#xff0c;或者在工具栏中选择开始 -> 数字 -> 自定义格式。在类型框中输入以下自定义格式&#xff1a; [>1000]0;[>100]0.0;G/通用格式解释&#xff1a; [>1000]0&…...

Java零基础入门笔记:(1-2)入门(简介、基础知识)

前言 本笔记是学习狂神的java教程&#xff0c;建议配合视频&#xff0c;学习体验更佳。 【狂神说Java】Java零基础学习视频通俗易懂_哔哩哔哩_bilibili - Java简介 Java是一种广泛使用的高级编程语言&#xff0c;具有简单、面向对象、分布式、多线程、动态性、健壮性和安全…...

Unreal5从入门到精通之使用 BindWidget 将 C++ 连接到 UMG 蓝图

文章目录 前言示例代码BindWidget使用C++的优缺点可选小部件其他特性前言 如果你开始制作基于 C++ 的 UI,你最常遇到的一个问题是: 如何使用 C++ 来控制蓝图创建的小部件? 这个问题的答案是BindWidget元属性。 BindWidget 示例 UPROPERTY(BlueprintReadWrite, meta = (…...

Java 基于 SpringBoot+Vue 的动漫平台(附源码,文档)

博主介绍&#xff1a;✌程序员徐师兄、8年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战*✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447…...

微信小程序 - 网络请求基础路径集中管理(基础路径集中管理策略、动态切换基础路径)

一、基础路径集中管理 在微信小程序项目开发中&#xff0c;经常会将请求的基础路径集中管理 这样可以避免在多个页面中重复定义&#xff0c;同时也方便后续维护与修改 二、基础路径集中管理策略 1、使用全局变量 微信小程序提供了 App 对象&#xff0c;可以在 app.js 中定义…...

Ubuntu 系统 cuda12.2 安装 MMDetection3D

DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(free)” 贵在坚持&#xff01; ---------------------------------------…...

DDD该怎么去落地实现(3)通用的仓库和工厂

通用的仓库和工厂 我有一个梦&#xff0c;就是希望DDD能够成为今后软件研发的主流&#xff0c;越来越多研发团队都转型DDD&#xff0c;采用DDD的设计思想和方法&#xff0c;设计开发软件系统。这个梦想在不久的将来是有可能达成的&#xff0c;因为DDD是软件复杂性的解决之道&a…...

【SpringBoot苍穹外卖】debugDay0 打开前端页面

在某一天学完后&#xff0c;电脑关机&#xff0c;再打开啥都忘了&#xff0c;记起来一点点&#xff0c;前端页面打不开&#xff0c;后端控制台一直循环出错。原来是下面这样哈哈。 查看端口是否被别的程序占用的操作步骤 winR输入cmd打开命令行 netstat -ano | findstr "8…...

康耐视CAM-CIC-10MR-10-GC工业相机

康耐视(COGNEX)的工业相机CAM-CIC-10MR-10-GC是CAM-CIC-10MR系列中的一款型号,主要应用于工业自动化检测和高精度视觉系统 基本参数与特性 分辨率与帧率: CAM-CIC-10MR-10-GC属于康耐视CIC系列,具备10MP(1000万像素)的分辨能力,帧率为10fps。该系列相机支持卷帘快门(R…...

华为昇腾服务器部署DeepSeek模型实战

在华为的昇腾服务器上部署了DeepSeek R1的模型进行验证测试&#xff0c;记录一下相关的过程。服务器是配置了8块910B3的显卡&#xff0c;每块显卡有64GB显存&#xff0c;根据DeepSeek R1各个模型的参数计算&#xff0c;如果部署R1的Qwen 14B版本&#xff0c;需要1张显卡&#x…...

做谷歌SEO需要了解哪些基本概念?

做谷歌SEO时&#xff0c;必须掌握一些基本的概念。首先是关键词。关键词是用户在搜索框里输入的词汇&#xff0c;它们直接影响到你网站的排名。所以&#xff0c;了解用户的搜索习惯、挑选合适的关键词&#xff0c;是每一个SEO优化者必须做的工作。 内容是关键。谷歌非常看重网…...

通过BingAPI爬取Bing半个月内壁纸

通过BingAPI爬取Bing半个月内壁纸 一、前言二、爬虫代码三、代码说明 一、前言 爬取Bing搜索网站首页壁纸的方式主要有两种&#xff0c;第一种为间接爬取&#xff0c;即并不直接对Bing网站发起请求&#xff0c;而是对那些收集汇总了Bing壁纸的网站发起请求&#xff0c;爬取图片…...

springboot021-基于协同过滤算法的个性化音乐推荐系统

&#x1f495;&#x1f495;作者&#xff1a; 小九学姐 &#x1f495;&#x1f495;个人简介&#xff1a;十年Java&#xff0c;Python美女程序员一枚&#xff0c;精通计算机专业前后端各类框架。 &#x1f495;&#x1f495;各类成品Java毕设 。javaweb&#xff0c;ssm&#xf…...

开关电源实战(一)宽范围DC降压模块MP4560

系列文章目录 文章目录 系列文章目录MP4560MP4560 3.8V 至 55V 的宽输入范围可满足各种降压应用 MOSFET只有250mΩ 输出可调0.8V-52V SW:需要低VF肖特基二极管接地,而且要靠近引脚,高压侧开关的输出。 EN:输入使能,拉低到阈值以下关闭芯片,拉高或浮空启动 COMP:Compens…...

【MySQL】我在广州学Mysql 系列——Mysql 日志管理详解

ℹ️大家好&#xff0c;我是练小杰&#xff0c;今天又是新的一周了&#xff0c;又该摆好心态迎接美好的明天了&#xff01;&#xff01;&#xff01;&#x1f606; 本文主要对Mysql数据库中的日志种类以及基本命令进行讨论&#xff01;&#xff01; 回顾&#xff1a;&#x1f4…...

《Zookeeper 分布式过程协同技术详解》读书笔记-2

目录 zk的一些内部原理和应用请求&#xff0c;事务和标识读写操作事务标识&#xff08;zxid&#xff09; 群首选举Zab协议&#xff08;ZooKeeper Atomic Broadcast protocol&#xff09;文件系统和监听通知机制分布式配置中心, 简单Demojava code 集群管理code 分布式锁 zk的一…...

HTML5+CSS多层级ol标签序号样式问题

在CSS中&#xff0c;ol标签用于创建有序列表&#xff0c;而多层级的ol标签可以通过CSS实现不同的序号样式。以下是一些常见的问题和解决方案&#xff1a; 1. 多层级ol的序号格式问题 默认情况下&#xff0c;多层级的ol标签会自动继承父级的序号格式&#xff0c;但有时我们可能…...

网络初始2:网络编程--基于UDP和TCP实现回显器

基础概念 1.发送端与接受端 在通过网络传输信息时&#xff0c;会有两个进程&#xff0c;接收端和发送端。 发送端&#xff1a;数据的发送方进程&#xff0c;即网络通信中的源主机。 接收端&#xff1a;数据的接收方进程&#xff0c;即网路通信中的目的主机。 2.Socet套接字…...

vtkCamera类的Dolly函数作用及相机拉近拉远

录 1. 预备知识 1.1.相机焦点 2. vtkCamera类的Dolly函数作用 3. 附加说明 1. 预备知识 要理解vtkCamera类的Dolly函数作用,就必须先了解vtkCamera类表示的相机的各种属性。  VTK是用vtkCamera类来表示三维渲染场景中的相机。vtkCamera负责把三维场景投影到二维平面,如…...

车载音频架构图详解(精简)

目录 上图是车载音频架构图,对这个图我们进行详细的分析 左边第一层 是 app 常用的类有MediaPlayer和MediaRecorder, AudioTrack和AudioRecorder 第二层 是framework提供给应用的多媒体功能的AP...

Android嵌套滑动造成的滑动冲突原理分析

嵌套滑动造成的滑动冲突原理分析 场景复现&#xff1a; CoordinatorLayout AppBarLayout Vertical RecyclerView Horizontal RecycleView Horizontal RecycleView 是Vertical RecyclerView的一个子view, CoordinatorLayout 实现了AppBarLayout 和 RecyclerView的协调联动…...

计算机专业知识【 轻松理解数据库四大运算:笛卡尔积、选择、投影与连接】

在数据库的世界里&#xff0c;有几个关键的运算操作&#xff0c;就像是神奇的魔法工具&#xff0c;能帮助我们对数据进行各种处理和组合。今天&#xff0c;咱们就来聊聊笛卡尔积运算、选择运算、投影运算和连接运算这四大运算&#xff0c;用超简单的例子让小白也能轻松理解。 …...

使用神经网络对驾驶数据进行道路类型分类

摘要 道路分类&#xff0c;了解我们是在城市、农村地区还是在高速公路上驾驶&#xff0c;可以提高现代驾驶员辅助系统的性能&#xff0c;并有助于了解驾驶习惯。本研究的重点是仅使用车速数据来普遍解决这个问题。已经开发了一种数据记录方法&#xff0c;用于为 On-board Diagn…...

S4D480 S4HANA 基于PDF的表单打印

2022年元旦的笔记草稿 SAP的表单打印从最早的SAPScripts 到后来的SMARTFORM&#xff0c;步入S4时代后由于Fiori的逐渐普及&#xff0c;更适应Web的Adobe Form成了SAP主流output文件格式。 目录 一、 基于PDF表单打印系统架构Interface 接口Form 表单ContextLayout 二、表单接…...

qt QOpenGLTexture详解

1. 概述 QOpenGLTexture 是 Qt5 提供的一个类&#xff0c;用于表示和管理 OpenGL 纹理。它封装了 OpenGL 纹理的创建、分配存储、绑定和设置像素数据等操作&#xff0c;简化了 OpenGL 纹理的使用。 2. 重要函数 构造函数&#xff1a; QOpenGLTexture(const QImage &image,…...

Deepseek-R1推理模型API接入调用指南 ChatGPT Web Midjourney Proxy 开源项目接入Deepseek教程

DeepSeek-R1和OpenAI o1模型都属于推理任务模型&#xff0c;两个模型各有优点&#xff1a;DeepSeek-R1 在后训练阶段大规模使用了强化学习技术&#xff0c;在仅有极少标注数据的情况下&#xff0c;极大提升了模型推理能力。在数学、代码、自然语言推理等任务上&#xff0c;性能…...

蓝耘智算携手DeepSeek,共创AI未来

&#x1f31f; 各位看官号&#xff0c;我是egoist2023&#xff01; &#x1f30d; 种一棵树最好是十年前&#xff0c;其次是现在&#xff01; &#x1f680; 今天来学习如何通过蓝耘智算使用DeepSeek R1模型 &#x1f44d; 如果觉得这篇文章有帮助&#xff0c;欢迎您一键三连&a…...

【网络编程】之数据链路层

【网络编程】之数据链路层 数据链路层基本介绍基本功能常见协议 以太网什么是以太网以太网协议帧格式数据链路层的以太网帧报文如何封装/解封装以及分用以太网通信原理传统的以太网与集线器现代以太网与交换机碰撞域的概念 Mac地址基本概念为什么要使用Mac地址而不是使用IP地址…...