Java中的CountDownLatch原理使用注意事项

CountDownLatch是Java并发工具包java.util.concurrent中的一个类,主要用于解决一个或多个线程等待一组操作完成的问题。它的核心原理是基于一个内部的计数器,当计数器的值减至0时,所有因调用await()方法而阻塞的线程将会被唤醒,从而继续执行。

CountDownLatch的原理

  1. 初始化:创建CountDownLatch时,需要传入一个整数作为计数器的初始值。这个值代表了需要等待的事件数目。
  2. 计数器减1:当一个事件发生时,调用countDown()方法使得计数器的值减1。
  3. 等待:调用await()方法的线程会阻塞,直到计数器的值变为0。await()方法有两个版本,一个是无参的,会无限期地等待;另一个接受超时时间作为参数,会在指定时间内等待计数器变为0,超时后线程会被唤醒。
  4. 唤醒线程:一旦计数器的值变为0,所有等待的线程都会被唤醒,然后继续执行后续的操作。

使用方式

下面是一个简单的CountDownLatch的使用示例:

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        final int threadCount = 5;
        CountDownLatch latch = new CountDownLatch(threadCount);

        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " is running.");
                // 模拟一些耗时的操作
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " finished.");
                // 减少计数器的值
                latch.countDown();
            }).start();
        }

        // 主线程等待所有子线程完成
        System.out.println("Main thread waiting...");
        latch.await();
        System.out.println("All threads have finished their tasks.");
    }
}

在这个例子中,主线程创建了一个CountDownLatch实例,初始计数器值为5。接着启动了5个线程,每个线程执行完自己的任务后,调用countDown()方法来减少计数器的值。主线程通过调用await()方法来等待所有的子线程完成,即计数器的值变为0。

注意事项

  • CountDownLatch是一个一次性使用的工具,一旦计数器的值达到0,就不能再被重置。如果需要重新使用,需要重新创建一个新的CountDownLatch实例。
  • CountDownLatch的计数器只能通过构造函数初始化,且初始化后的值只能减少,不能增加。
  • await()方法抛出InterruptedException,因此在使用时需要处理这个异常,通常可以通过恢复线程的中断状态来处理。
  • 如果一个线程在调用await()之前已经被中断,那么await()会立即抛出InterruptedException并清除线程的中断状态。
  • 在使用CountDownLatch时,确保所有调用countDown()的线程最终都会调用它,否则等待的线程可能永远处于阻塞状态。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用中国大陆镜像源安装最新版的 docker Deamon

在一个智算项目交付过程中&#xff0c;出现了新建集群中的全部 docker server V19 进程消失、仅剩 docker server 的 unix-socket 存活的现象。 为了验证是否是BD产品研发提供的产品deploy语句缺陷&#xff0c;需要在本地环境上部署一个简单的 docker Deamon 环境。尴尬的是&a…

强化学习后的数学原理:随机近似与梯度下降

概述 这节课的作用&#xff1a; 本节课大纲如下&#xff1a; Motivating examples 先回顾一下 mean estimation &#xff1a; 为什么总数反复提到这个 mean estimation&#xff0c;就是因为 RL 当中有非常多的 expectation&#xff0c;后面就会知道除了 state value 这些定义…

传统视觉Transformer的替代者:交叉注意力Transformer(CAT)

传统视觉Transformer的替代者&#xff1a;交叉注意力Transformer&#xff08;CAT&#xff09; 在深度学习的世界里&#xff0c;Transformer架构以其在自然语言处理&#xff08;NLP&#xff09;领域的卓越表现而闻名。然而&#xff0c;当它进入计算机视觉&#xff08;CV&#x…

Hilbert编码 思路和scala 代码

需求&#xff1a; 使用Hilbert 曲线对遥感影像瓦片数据进行编码&#xff0c;获取某个区域的编码值即可 Hilbert 曲线编码方式 思路 大致可以对四个方向的数据进行归类 左下左上右上右下 这个也对应着编码的顺序 思考在不同Hilbert深度&#xff08;阶&#xff09;情况下的…

AutoX.js某音自动评论(一个函数,5秒完成)

背景 某音自动化评论&#xff0c;步骤简单&#xff0c;对版本兼容性要高&#xff08;不用节点id定位&#xff09; 思路 通过Intent直接跳转到视频*利用文字&#xff0c;描述&#xff08;正则&#xff09;等匹配输入框&#xff0c;发表评论 效果 某音自动化评论 已经封装成一…

专题二:Spring源码编译

目录 下载源码 配置Gradle 配置环境变量 配置setting文件 配置Spring源码 配置文件调整 问题解决 完整配置 gradel.properties build.gradle settiings.gradel 在专题一&#xff1a; Spring生态初探中我们从整体模块对Spring有个整体的印象&#xff0c;现在正式从最…

C盘扩容/扩大C盘的12个有效操作方法

对于许多计算机用户来说&#xff0c;C盘空间可能会成为一个问题&#xff0c;尤其是那些将计算机广泛用于工作、游戏和多媒体目的的用户。如果您发现C驱动器上的空间不足&#xff0c;则需要对其进行扩展以提高系统的整体性能。在这篇文章中&#xff0c;我们将探讨C盘扩展的12种操…

【计算智能】遗传算法(二):基本遗传算法在优化问题中的应用【实验】

前言 本系列文章架构概览&#xff1a; 本文将介绍基本遗传算法在解决优化问题中的应用,通过实验展示其基本原理和实现过程&#xff1a;选取一个简单的二次函数作为优化目标&#xff0c;并利用基本遗传算法寻找其在指定范围内的最大值。 2. 基本遗传算法&#xff08;SGA&#x…

Laravel 谨慎使用Storage::append()

在 driver 为 local 时&#xff0c;Storage::append()在高并发下&#xff0c;会存在丢失数据问题&#xff0c;文件被覆写&#xff0c;而非尾部添加&#xff0c;如果明确是本地文件操作&#xff0c;像日志写入&#xff0c;建议使用 Illuminate\Filesystem\Filesystem或者php原生…

跨境干货|最新注册Google账号方法分享

谷歌账号对做跨境外贸业务的人来说是刚需&#xff0c;目前来说大部分的海外社媒平台、工具都可以用谷歌账号来注册。但是仍然有很多朋友并不知道如何注册这个谷歌账号&#xff0c;今天就来给大家分享2个注册谷歌账号的方法&#xff0c;一个是手机号注册&#xff0c;一个是如何跳…

品牌营销新趋势:独立站如何与TikTok达人互动共赢

在当今数字化营销时代&#xff0c;独立站与TikTok达人的互动营销已成为一种高效的推广方式。通过精心设计的互动环节&#xff0c;独立站不仅能够增强用户参与感&#xff0c;还能显著提升带货效果。本文Nox聚星将和大家探讨独立站如何与TikTok达人进行高效互动&#xff0c;吸引用…

如何有效管理你的Facebook时间线?

Facebook作为全球最大的社交平台之一&#xff0c;每天都有大量的信息和内容在用户的时间线上展示。有效管理你的Facebook时间线&#xff0c;不仅可以提升用户体验&#xff0c;还能够帮助你更好地控制信息流和社交互动。本文将探讨多种方法和技巧&#xff0c;帮助你有效管理个人…

开发者评测|操作系统智能助手OS Copilot

操作系统智能助手OS Copilot 文章目录 操作系统智能助手OS CopilotOS Copilot 是什么优势功能 操作步骤创建实验重置密码创建Access Key配置安全组安装 os-copilot环境变量配置功能评测命令行模式多轮交互模式 OS Copilot 产品体验评测反馈OS Copilot 产品功能评测反馈 参考文档…

C++基础(七):类和对象(中-2)

上一篇博客学的默认成员函数是类和对象的最重要的内容&#xff0c;相信大家已经掌握了吧&#xff0c;这一篇博客接着继续剩下的内容&#xff0c;加油&#xff01; 目录 一、const成员&#xff08;理解&#xff09; 1.0 引入 1.1 概念 1.2 总结 1.2.1 对象调用成员函数 …

使用 mongo2neo4j 和 SemSpect 通过各种方式进行图探索

用于可视化和探索每个 MEAN 堆栈背后的数据图的 ETL 您是否正在努力回答有关 MEANS Web 服务数据的紧急问题&#xff1f;哪里有 BI 可以快速回答“上个季度哪些亚洲的artisan.plus 用户触发了订单&#xff1f;”这个问题&#xff0c;而无需编写查询&#xff1f;使用 mongo2neo4…

Linux:进程间通信(一.初识进程间通信、匿名管道与命名管道、共享内存)

上次结束了基础IO&#xff1a;Linux&#xff1a;基础IO&#xff08;三.软硬链接、动态库和静态库、动精态库的制作和加载&#xff09; 文章目录 1.认识进程间通信2.管道2.1匿名管道2.2pipe()函数 —创建匿名管道2.3匿名管道的四种情况2.4管道的特征 3.基于管道的进程池设计4.命…

FineBI在线学习资源-数据处理

FineBI在线学习资源汇总&#xff1a; 学习资源 视频课程 帮助文档 问答 数据处理学习文档&#xff1a; 相关资料&#xff1a; 故事背景概述-https://help.fanruan.com/finebi6.0/doc-view-1789.html 基础表处理-https://help.fanruan.com/finebi6.0/doc-view-1791.html …

软件设计之Java入门视频(11)

软件设计之Java入门视频(11) 视频教程来自B站尚硅谷&#xff1a; 尚硅谷Java入门视频教程&#xff0c;宋红康java基础视频 相关文件资料&#xff08;百度网盘&#xff09; 提取密码&#xff1a;8op3 idea 下载可以关注 软件管家 公众号 学习内容&#xff1a; 该视频共分为1-7…

Ubuntu 24.04 上安装 Kubernetes,超级详细的教程!

Kubernetes 是一个免费的开源容器编排工具&#xff0c;它允许基于容器的应用程序的自动化部署、扩展和管理。 我们将介绍如何使用 Kubeadm 逐步在 Ubuntu 24.04 上安装 Kubernetes 此次演示中&#xff0c;我们将使用以下三个 Ubuntu 24.04 实例 Instance 1 : Master Node (k…

计算机视觉——opencv快速入门(二) 图像的基本操作

前言 上一篇文章中我们介绍了如何配置opencv&#xff0c;而在这篇文章我们主要介绍的是如何使用opencv来是实现一些常见的图像操作。 图像的读取&#xff0c;显示与存储 读取图像文件 在opencv中我们利用imread函数来读取图像文件,函数语法如下&#xff1a; imagecv2.imre…