CountDownLatch闭锁原理解析

CountDownLatch闭锁原理解析

在Java并发编程中,CountDownLatch是一个常用的工具类,用于实现闭锁(latch)。闭锁是一种常见的同步机制,用于控制线程的执行流程,确保某些线程在执行之前满足特定的条件。CountDownLatch尤其在多线程协作场景中非常重要,例如,当一个线程需要等待其他多个线程完成各自的工作后才能执行下一步操作时,CountDownLatch可以发挥巨大作用。

CountDownLatch实现

CountDownLatch是一个Java并发库中的类,位于java.util.concurrent包中。它提供了两个主要的方法:await()countDown()await()方法用于阻塞当前线程,直到所有参与方都调用了countDown()方法,否则不会继续执行。countDown()方法则用于减少 latch 的计数,表示一个参与方已经完成自己的任务。当计数减为0时,所有因调用await()而阻塞的线程将恢复执行。

CountDownLatch的核心是一个内部类CountDownLatch$CountDownLatchlatch,它实现了AbstractQueuedSynchronizer(AQS)。这个内部类通过维护一个计数器(计数为参与方的数量)和一个队列来工作。当一个线程调用await()方法时,它会被放入队列中并阻塞,同时会减少计数器的值。当一个线程调用countDown()方法时,计数器会减少1,如果计数器值为0,那么队列中的所有线程都将被唤醒并从阻塞状态变为非阻塞状态,可以继续执行。

工作原理分析

CountDownLatch的工作原理可以简单概括为:在多线程协作中,一些线程在执行完自己的任务之后,会调用countDown()方法来减少计数器的值。当计数器值为0时,所有因调用await()而阻塞的线程将恢复执行。

这个机制确保了只有当所有参与方都完成任务后,才允许某些线程继续执行。这对于多线程之间的同步和协调非常有用。例如,考虑一个场景,有一个任务需要被多个线程分别处理,并且只有在所有线程都完成后,主线程才继续执行。在这种情况下,我们可以使用CountDownLatch来实现这个需求。

简单Java代码示例

以下是一个简单的Java代码示例来说明如何使用CountDownLatch:

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;public class CountDownLatchExample {public static void main(String[] args) throws InterruptedException {final CountDownLatch latch = new CountDownLatch(3); // 3参与方// 创建3个线程分别执行任务并调用countDown()方法new Thread(() -> {System.out.println("Thread 1 start");try {TimeUnit.SECONDS.sleep(2); // 模拟任务执行时间} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread 1 end");latch.countDown(); // 完成任务后减少计数器值}).start();new Thread(() -> {System.out.println("Thread 2 start");try {TimeUnit.SECONDS.sleep(1); // 模拟任务执行时间} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread 2 end");latch.countDown(); // 完成任务后减少计数器值}).start();new Thread(() -> {System.out.println("Thread 3 start");try {TimeUnit.SECONDS.sleep(3); // 模拟任务执行时间} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread 3 end");latch.countDown(); // 完成任务后减少计数器值}).start();// 主线程等待所有参与方完成任务后继续执行latch.await();System.out.println("All tasks completed, main thread continues.");}
}

在上面的代码示例中,我们创建了一个CountDownLatch实例并设定参与方数量为3。然后创建了3个线程来模拟任务执行,每个线程在完成任务后都会调用countDown()方法。主线程则通过await()方法等待所有参与方完成任务。当所有参与方都调用了countDown()方法,计数器减为0,await()方法返回,主线程继续执行。

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

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

相关文章

DIY一个智能音箱

十一假期里将蓝牙音箱改造成一个智能音箱, 参考了网上的实现方法, 后台的大语言模型使用的是百度的文心一言. 账号 Picovoice 唤醒词服务 https://console.picovoice.ai/ 我绑定了github账号. 访问https://picovoice.ai/,注册账号,然后进入控制台, 目前不…

java 无感hook实现(修改jdk)

背景 1 工作需要,需要修改一个java的程序逻辑,之前都是用的frida修改的,但是现在的工作场景,重视效率,所以frida这种重工具被pass了,只能重新选其他工具,初始的时候是想用java本身的一些修改工…

纸、纸板和纸制品 有效回收组分的测定

声明 本文是学习GB-T 42944-2023 纸、纸板和纸制品 有效回收组分的测定. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件描述了纸、纸板和纸制品中有效回收组分的测定方法。 本文件适用于各种纸、纸板和纸制品,也适用于铝箔…

微信小程序通过 movable-area 做一个与vuedraggable相似的上下拖动排序控件

因为只是做个小案例 我就直接代码写page页面里了 其实很简单 组件稍微改一下就好了 wxss /* 设置movable-area的宽度 */ .area{width: 100%; }/* a b c 每条元素的样式 */ movable-view {width: 100%;background-color: red;height: 40px;line-height: 40px;color: #FFFFFF;tex…

docker命令,免sudo

docker命令,免sudo 一、创建docker用户组 # 查看有无用户组 cat /etc/group | grep docker # 若无,创建 sudo groupadd docker二、添加当前用户到用户组 sudo gpasswd -a ${USER} docker三、重启docker服务 sudo service docker restart四、重启会话…

day

#include <iostream> using namespace std; class Per {//算术运算符friend const Per operator(const Per &k1,const Per &k2);friend const Per operator-(const Per &k1,const Per &k2);friend const Per operator*(const Per &k1,const Per &…

3ds Max渲染太慢?创意云“一键云渲染”提升3ds Max渲染体验

&#xfeff;在数字艺术设计领域&#xff0c;3ds Max是广泛使用的三维建模和渲染软件之一。然而&#xff0c;许多用户都面临着一个共同的问题&#xff1a;渲染速度太慢。渲染一帧画面需要耗费数小时&#xff0c;让人无法忍受。除了之前给大家介绍的几种解决方法外&#xff1a; …

uvm中transaction的response和id的解读

在公司写代码的时候发现前辈有一段这样的代码&#xff1a; ....//其他transaction uvm_create(trans);........ uvm_send(trans); tmp_id trans.get_transaction_id(); get_response(rsp,tmp_id); 如果前面有其他transaction&#xff0c;这段代码里的get_response不带id的话…

C#学习系列相关之多线程(五)----线程池ThreadPool用法

一、线程池的作用 线程池是一种多线程处理形式&#xff0c;处理过程中将任务添加到队列&#xff0c;然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认堆栈大小&#xff0c;以默认的优先级运行&#xff0c;并处于多线程单元中。如果某个线程在托管…

Vue3中reactive, onMounted, ref,toRaw,conmpted 使用方法

import { reactive, onMounted, ref,toRaw,conmpted } from vue; vue3中 reactive &#xff0c;ref &#xff0c; toRaw&#xff0c;watch&#xff0c;conmpted 用法 toRaw 返回原响应式对象 用法&#xff1a; const rowList toRaw(row) reactive:ref: ref和reactive都是V…

快讯|Tubi 有 Rabbit AI 啦

在每月一期的 Tubi 快讯中&#xff0c;你将全面及时地获取 Tubi 最新发展动态&#xff0c;欢迎星标关注【比图科技】微信公众号&#xff0c;一起成长变强&#xff01; Tubi 推出 Rabbit AI 帮助用户找到喜欢的视频内容 Tubi 于今年九月底推出了 Rabbit AI&#xff0c;这是一项…

有效回收组分含量

声明 本文是学习GB-T 42944-2023 纸、纸板和纸制品 有效回收组分的测定. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件描述了纸、纸板和纸制品中有效回收组分的测定方法。 本文件适用于各种纸、纸板和纸制品&#xff0c;也适用于铝箔…

AndroidStudio报错:Plugin with id ‘kotlin-android‘ not found.

第一步 要在自己的项目的build.gradle的buildscript中添加ext.kotlin_version 1.3.72 第二步 然后在dependencies里添加classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 大体如下&#xff1a; buildscript {ext.kotlin_version 1.3.72r…

Qt如何在视频画面上新增车道线显示

在Qt中向视频画面上新增车道线显示通常需要以下步骤&#xff1a; 1.获取视频流或帧数据&#xff1a;首先&#xff0c;您需要获取视频流或视频帧的数据。您可以使用Qt的多媒体模块或其他第三方库来捕获视频流&#xff0c;或者从视频文件中读取帧数据。这将是您要在其上绘制车道…

【自动驾驶】PETR/PETRv2/StreamPETR论文分析

1.PETR PETR网络结构如下&#xff0c;主要包括image-backbone, 3D Coordinates Generator, 3D Position Encoder, transformer Decoder 1.1 Images Backbone 采用resnet 或者 vovNet,下面的x表示concatenate 1.2 3D Coordinates Generator 坐标生成跟lss类似&#xff0c;假…

如何对比github中不同commits的区别

有时候想要对比跨度几十个commits之前的代码区别&#xff0c;想直接使用github的用户界面。可以直接在官网操作。 示例 首先要创建一个旧commit的branch。进入该旧的commit&#xff0c;然后输入branch名字即可。 然后在项目网址后面加上compare即可对比旧的branch和新的bran…

【轻松玩转MacOS】故障排除篇

引言 在使用 MacOS 时&#xff0c;遇到故障是在所难免的。不要担心&#xff0c;这篇文章将为您提供一些常见的故障排除步骤&#xff0c;并介绍如何联系苹果的支持团队寻求帮助。让我们一起来看看吧&#xff01; 一、常见的故障排除步骤 1.1 网络连接问题 如果你发现你的Mac…

初识华为云数据库GaussDB for openGauss

01 前言 GaussDB是华为自主创新研发的分布式关系型数据库。该产品具备企业级复杂事务混合负载能力&#xff0c;同时支持分布式事务&#xff0c;同城跨AZ部署&#xff0c;数据0丢失&#xff0c;支持1000的扩展能力&#xff0c;PB级海量存储。同时拥有云上高可用&#xff0c;高可…

【postgresql】ERROR: integer out of range

查询文章都类似&#xff0c;只是类型没有对应上&#xff0c;根据实际情况处理。 前情 使用postgresql数据库数据库ID类型int4实体类代码private Long id; 异常 ### Cause: org.postgresql.util.PSQLException: ERROR: integer out of range ; ERROR: integer out of range;…

Go 语言切片扩容规则是扩容2倍?1.25倍?到底几倍

本次主要来聊聊关于切片的扩容是如何扩的&#xff0c;还请大佬们不吝赐教 切片&#xff0c;相信大家用了 Go 语言那么久这这种数据类型并不陌生&#xff0c;但是平日里聊到关于切片是如何扩容的&#xff0c;很多人可能会张口就来&#xff0c;切片扩容的时候&#xff0c;如果老…