同步计数器 CountDownLatch(闭锁)

并发编程之CountDownLatch原理与应用 CountDownLatch是一个同步计数器,他允许一个或者多个线程在另外一组线程执行完成之前一直等待,基于AQS共享模式实现的。 是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作来。 阅读详情

一、概念

CountDownLatch 是java.util.concurrent中的一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是互斥)的作用。机制是只要提供的多个(具体数量等于初始化CountDownLatch时count的值)线程都达到了预期状态或者完成了预期工作时触发事件,其他线程可以等待这个事件来触发自己后续的工作。等待的线程可以是多个,即 CountDownLatch 可以唤醒多个等待的线程。到达自己预期状态的线程会调用 CountDownLatch 的 countDown(),而等待的线程会调用 CountDownLatch 的 await()。

CountDownLatch 能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减 1。当计数器的值为 0 时,表示所有的线程都已经完成一些任务,然后在 CountDownLatch 上等待的线程就可以恢复执行接下来的任务。

注意:它是一次性的,计算器的值只能在构造方法中初始化一次,之后再没有任何机制对其设置值,当 CountDownLatch 使用完毕后,它不能再次被使用。

二、用法

1️⃣某一线程在开始运行前等待 n 个线程执行完毕。CountDownLatch 的计数器初始化new CountDownLatch(n),每当一个任务线程执行完毕,就将计数器减 1 即执行countdownLatch.countDown(),当计数器的值变为 0 时,在 CountDownLatch 上 await() 的线程就会被唤醒。一个典型应用场景就是启动一个服务时,主线程需要等待多个组件加载完毕,之后再继续执行。

2️⃣实现多个线程开始执行任务的最大并行性。注意是并行性,不是并发,强调的是多个线程在某一时刻同时开始执行。类似于赛跑,将多个线程放到起点,等待发令枪响,然后同时开跑。做法是初始化一个共享的 CountDownLatch(1),将其计算器初始化为 1,多个线程在开始执行任务前首先 countdownlatch.await(),当主线程调用 countDown() 时,计数器变为 0,多个线程同时被唤醒。

三、方法说明

1️⃣public void countDown()递减锁存器的计数,如果计数到达零,则释放所有等待的线程。如果当前计数大于零,则将计数减少。

2️⃣public void await() throws InterruptedException {};调用该方法的线程会被挂起,它会等待直到 count 值为 0 才继续执行。

3️⃣public boolean await(long timeout,TimeUnit unit) throws InterruptedException
timeout—>要等待的最长时间;unit—>timeout 参数的时间单位。和 await() 类似,只不过等待一定的时间后 count 值还没变为 0 的话就会继续执行。

使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。如果当前计数为零,此方法立刻返回 true。如果当前计数大于零,出于线程调度目的,将禁用当前线程,且在发生以下三种情况之一前,该线程将一直出于休眠状态:

  1. 由于调用 countDown(),计数到达零。
  2. 其他某个线程中断当前线程。
  3. 已超出指定的等待时间。
  • 如果计数到达零,该方法返回 true。
  • 如果当前线程,在进入此方法时已经设置了该线程的中断状态;或者在等待时被中断,则抛出 InterruptedException,并且清除当前线程的已中断状态。
  • 如果超出了指定的等待时间,则返回 false。如果该时间小于等于零,则该方法根本不会等待。

四、方法示例

1️⃣主线程等待子线程执行完成再执行

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountdownLatchTest1 {
    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(3);
        final CountDownLatch latch = new CountDownLatch(3);
        for (int i = 0; i < 3; i++) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("子线程" + Thread.currentThread().getName() + "开始执行");
                        Thread.sleep((long) (Math.random() * 10000));
                        System.out.println("子线程" + Thread.currentThread().getName() + "执行完成");
                        latch.countDown();//当前线程调用此方法,则计数减1
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            service.execute(runnable);
        }

        try {
            System.out.println("主线程" + Thread.currentThread().getName() + "等待子线程执行完成...");
            latch.await();//阻塞当前线程,直到计数器的值为0
            service.shutdown();
            System.out.println("主线程" + Thread.currentThread().getName() + "开始执行...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2️⃣百米赛跑,4 名选手等待裁判口令,裁判一声口令,选手听到后同时起跑,当所有选手到达终点,裁判进行汇总排名

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountdownLatchTest2 {
    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();
        final CountDownLatch cdOrder = new CountDownLatch(1);
        final CountDownLatch cdAnswer = new CountDownLatch(4);
        for (int i = 0; i < 4; i++) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("选手" + Thread.currentThread().getName() + "正在等待裁判发布口令");
                        cdOrder.await();
                        System.out.println("选手" + Thread.currentThread().getName() + "已接受裁判口令");
                        Thread.sleep((long) (Math.random() * 10000));
                        System.out.println("选手" + Thread.currentThread().getName() + "到达终点");
                        cdAnswer.countDown();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            service.execute(runnable);
        }
        try {
            Thread.sleep((long) (Math.random() * 10000));
            System.out.println("裁判" + Thread.currentThread().getName() + "即将发布口令");
            cdOrder.countDown();
            System.out.println("裁判" + Thread.currentThread().getName() + "已发送口令,正在等待所有选手到达终点");
            cdAnswer.await();
            System.out.println("所有选手都到达终点");
            System.out.println("裁判" + Thread.currentThread().getName() + "汇总成绩排名");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        service.shutdown();
    }
}

3️⃣确保三个线程顺序执行

import java.util.concurrent.CountDownLatch;
public class CountdownLatchTest3 {
	// T1、T2、T3三个线程顺序执行
	public static void main(String[] args) {
		CountDownLatch c0 = new CountDownLatch(0); //计数器为0
		CountDownLatch c1 = new CountDownLatch(1); //计数器为1
		CountDownLatch c2 = new CountDownLatch(1); //计数器为1
                
        //c0为0,t1可以执行。t1的计数器减1
		Thread t1 = new Thread(new Work(c0, c1));
        //t1的计数器为0时,t2才能执行。t2的计数器c2减1
		Thread t2 = new Thread(new Work(c1, c2));
        //t2的计数器c2为0时,t3才能执行
		Thread t3 = new Thread(new Work(c2, c2));
		
		t1.start();
		t2.start();
		t3.start();
	}

	//定义Work线程类,需要传入开始和结束的CountDownLatch参数
	static class Work implements Runnable {
		CountDownLatch c1;
		CountDownLatch c2;
		Work(CountDownLatch c1, CountDownLatch c2) {
			super();
			this.c1 = c1;
			this.c2 = c2;
		}
		public void run() {
			try {
				c1.await();//前一线程为0才可以执行
				System.out.println("thread start:" + Thread.currentThread().getName());
				c2.countDown();//本线程计数器减少
			} catch (InterruptedException e) {
			}
		}
	}
}
有限元分析必看:如何用ANSYS检查关键区域的网格质量(附操作截图) 本文聚焦有限元分析中决定仿真精度的关键环节,详细讲解了如何利用ANSYS Workbench对关键区域进行网格质量检查与优化。文章提供了从思维转变、实战操作到指标解读的完整流程,强调通过命名选择、Worksheet过滤器等工具实现定向检查,并给出了针对结构分析的关键区域网格质量阈值建议,帮助工程师提升仿真结果的可靠性与效率。 阅读详情

相关推荐

【模型转换】将.mindir文件转换成.ms文件(Windows篇)

首先需要在MindSpore中训练好并经过评估可用的模型,可以以标准格式(例如onnx, mindir等)导出,得到.mindir模型文件(例如lenet.mindir)。为了将模型部署到自定义应用中,还需要将其转换为更为紧凑和高效的ms格式模型,用于在MindSpore-Lite环境中推理,这可以通过MindSpore Lite提供的模型转换工具converter_lite完成。

qq_42962847的博客 1425

CountDownLatch的理解和使用

CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)。 CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成一些任务,然后在CountDownLatch上等待的线程就可以恢复执行接下来的任务。

秃头的博客 472

MODTRAN5.2.1安装配置

MODTRAN5.2.1安装配置

Home 4256

CountDownLatch用法详解

CountDownLatch用法详解 CountDownLatch使用场景 线程计数器 用于线程执行任务,计数 等待线程结束 用法一: 等待所有的事情都做完 //程序计数器 CountDownLatch countDownLatch = new CountDownLatch(2); //2个线程 ExecutorService executorService = Executors.newFixedThreadPool(2);

. 3万+

MMSE (Minimum Mean Square Error)均衡原理讲解

MMSE是一种将接收数据的MSE(均方误差)最小化的模型。有了这句话,很多问题就会在你的脑海中蹦出来。 什么是均方误差?最小化MSE "的物理含义是什么? 等等。 让我们从一个我们现在已经非常熟悉的通道模型开始。(我希望你现在也熟悉下面的表达方式。) MMSE作为一种均衡器,是一种后处理算法,它可以帮助我们找出接收到的数据,使之尽可能地接近原始数据(传输数据)。简而言之,MMSE中最重要的步骤是找到一个如下图所示的矩阵G。如果我们假设没有噪声,这个[G]矩阵可以简单的作为信道矩阵(H^-1)的倒数。但

Celeste的博客 4万+

ArcGIS属性表汉字转拼音

接着我安装了一个编辑器“PyCharm Community Edition 2019.3.3\bin\pycharm64.exe”,在里面添加“pypinyin”包,然后将其设置为arcgis的编辑器和调试程序,还是失败;我在10.6的机器上折腾了上面几步,直到两周后脚本突然运行成功,我也不确定是哪一步导致pypinyin包配置成功,因此将心得体会写出来,如果过一段时间,打开10.2的机器运行脚本成功了,再写后续.......,按照“配置方法1:”进行尝试,显示配置失败。

2301_77413856的博客 1295

CountDownLatch 用法和详解

CountDownLatch是多线程控制的一种工具,它被称为门阀、计数器或者闭锁。这个工具经常用来用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)。下面我们就来一起认识一下 CountDownLatch 认识 CountDownLatch CountDownLatch 能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。它相当于是一个计数器,这个计数器的初始值就是线程的数量,每当一个任务完成后,计数器的值就会减一,当计数器的值为 0 时,表示所有的线程都已经...

胖大海 1万+

ONVIF协议简介与协议测试工具使用详解

Onvif协议及协议测试工具使用详解

dvlinker的技术专栏 3万+

CountDownLatch介绍和使用【Java多线程必备】

CountDownLatch介绍、特性、注意事项、使用案例(干货满满)

Mr.绵羊的知识星球 3万+

一文吃透:从零到一开发一套 ABAP RAP 应用的完整路径

ABAP RAP开发实战摘要 本文系统介绍了ABAP RESTful Application Programming Model (RAP)在企业级应用开发中的实施路径。文章以出差申请业务场景为例,详细拆解了RAP开发的六步主线流程: 数据库表设计:规范主键、审计字段设计 CDS数据建模:通过视图定义业务对象实体及关联 行为定义与实现:使用BDEF声明事务规则,Behavior Pool类实现业务逻辑 业务对象投影:裁剪服务接口视图 服务定义与绑定:按OData协议暴露服务 UI集成测试:支持Fiori E

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 508

Vue3 - 详细实现流程图编辑器可视化平台示例代码,打造前端web网页流程图在线编辑绘制操作展示,vue3自定义绘制流程图在页面上画流程图功能(提供各种操作按钮及节点控件,界面美观交互式流程图插件)

vue3,绘制流程图,在线流程图制作,在vue3中实现流程图,vue3做一个制作流程图的功能,vue3流程图组件,vue3流程图,流程图绘制展示,vue3流程图可视化在线编辑源码,基于VUE3的在线绘制流程图工具,vue3+logicflow流程图,绘制动态流程图并自定义节点和线,vue使用logicFlow绘制流程图,生成各种流程图图形可连接点移除,基于Vue的流程图组件,工作流程图,流程编辑器,vue3流程组件,vue-flow绘制流程图,绘制流程图示例demo,vue3 logicflow流程图使用教

🏆 前端领域优质创作者 9967

CountDownLatch详解

概述 CountDownLatch概念 CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,用来作为线程间的通信而不是互斥作用。 CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。 使用一个计数器进行实现,计数器初始值就是线程的数量。 当每个被计数的线程完成任务后,计数器值减一,当计数器的值为0时,表示所有线程都已经完成了任务,然后在CountDownLatch上等待的线程就可以恢复执行。 CountDownLatch的用法 ...

抽象的螺旋 2万+

61、神经科学中的分岔与双分子反应研究

本文探讨了神经科学中的分岔现象与双分子反应建模。在神经元网络中,通过分析四细胞网络的呼吸节律振荡,揭示了分岔对振荡频率和占空比的影响,并区分了单神经元与网络层面的分岔特性。在神经群体模型中,系统参数变化引发的分岔可导致振荡、混沌等动态行为转变,文中详细介绍了局部分岔、全局分岔和高余维分岔的机制,并以Jansen-Rit模型为例展示了输入水平变化下的分岔过程。在分子层面,重点介绍了MWC模型在描述配体与多位点蛋白质结合中的应用,涵盖其构象状态、平衡常数及统计因子。研究表明,分岔理论和双分子反应建模为理解神经系

yog99的博客 80

AQS应用-CountDownLatch

生活 代码无非是生活现实场景的翻译,把某些场景翻译成代码,即简单又复杂。 AQS中的应用也与我们的生活息息相关。 场景 今天来看一个有趣的场景,经历过学生时代的,都对那段必须跑的长跑深恶痛绝,发令枪响开跑,然后等到所有人跑完,老师才会把大家召集起来统一公布成绩。 这个场景用程序来模拟,实际就是N个线程执行操作,等全部执行完了,才执行某一个特定操作。 countDownLatch正是一个能提供如此功...

开始写bug~~~ 329

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

并发工具类CountDownLatch

/* * * @since 1.5 * @author Doug Lea */ public class CountDownLatch { /** * CountDownLatch 的内置类,用户同步计数控制. * 使用AQS状态表示计数 */ private static final class Sync extends AbstractQu...

qq_1411的博客 176

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

CountDownLatch分析

文章目录(一)概念简介(二)使用场景(三)特点(四)CountDownLatch源码分析(1)构造函数(2)await方法(核心)(3)countDown方法(核心) (一)概念简介 CountDownLatch是一个阻塞部分线程直到其他线程执行完成后唤醒的同步计数器,核心是其内部类Sync继承于AQS,同时也是利用的AQS的同步原理,也称之为闭锁。 (二)使用场景 当主线程进行执行时,利用构造方法初始化一个同步数state(AQS原理),主线程调用await方法进行阻塞主线程即谁调用谁阻塞,其它线程调用c

小萌新的博客 1007

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

同步计数器 CountDownLatch

CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行. CountDownLatch 是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。 主要方法有: CountDownLat...

weixin_30932215的博客 133

同步机制之--java之CountDownLatch闭锁

CountDownLatch闭锁 1、类介绍 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数初始化 CountDownLatch。CountDownLatch类是一个同步计数器,构造时传入int参数,该参数就是计数器的初始值,每调用一次countDown()方法,计数器减1,计数器大于0 时,await()方法会阻塞程序继续执行。由于调用了 ...

weixin_34399060的博客 100

Java多线程--同步计数器CountDownLatch

正如每个Java文档所描述的那样,CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。在Java并发中,countdownlatch的概念是一个常见的面试题,所以一定要确保你很好的理解了它。在这篇文章中,我将会涉及到在Java并发编 程中跟CountDownLatch相关的以下几点: 目录 CountDownLatch是什么

非淡泊无以明志,非宁静无以致远 407

JUC多线程:CountDownLatch、CyclicBarrier、Semaphore同步器原理总结

1、CountDownLatch,闭锁,主要作用是使一个或一组线程在其他线程执行完毕之前,一直处于等待状态,直到其他线程执行完成后再继续执行。 2、CyclicBarrier,循环栅栏,通过 CyclicBarrier 可以实现一组线程之间的相互等待,当所有线程都到达屏障点之后再执行后续的操作。 3、Semaphore 信号量,主要用于控制并发访问共享资源的线程数量,依赖 AQS 的变量 state 作为许可证 permit,通过控制许可证的数量,来保证线程之间的配合。

张维鹏的博客 1万+

面试官:说下CountDownLatch、CyclicBarrier、Semaphore同步器原理

CountDownLatch,闭锁,就是一个基于 AQS 共享模式的同步计数器,它内部的方法都是围绕 AQS 实现的。主要作用是使一个或一组线程在其他线程执行完毕之前,一直处于等待状态,直到其他线程执行完成后再继续执行。

Java后端架构V 269

JUC多线程CountDownLatch、CyclicBarrier、Semaphore 同步器原理

CountDownLatch,闭锁,就是一个基于 AQS 共享模式的同步计数器,它内部的方法都是围绕 AQS 实现的。主要作用是使一个或一组线程在其他线程执行完毕之前,一直处于等待状态,直到其他线程执行完成后再继续执行。

z1ztai的博客 255

并发编程应用场景_并发编程之CountDownLatch原理与应用

作者公众号:一角钱技术(org_yijiaoqian)前言控制并发流程的工具类,作用就是帮助我们程序员更容易的让线程之间合作,让线程之间相互配合来满足业务逻辑。比如让线程A等待线程B执行完毕后再执行等合作策略。控制并发流程的工具类主要有:简介背景CountDownLatch是在Java1.5被引入,跟它一起被引入的工具类还有CyclicBarrier、Semaphore、Concurrenthas...

weixin_33308577的博客 294

JUC多线程:CountDownLatch、CyclicBarrier、Semaphore 同步器原理

一、CountDownLatch:1、什么是 CountDownLatch:CountDownLatch,闭锁,就是一个基于 AQS 共享模式的同步计数器,它内部的方法都是围绕 AQS 实现的。主要作用是使一个或一组线程在其他线程执行完毕之前,一直处于等待状态,直到其他线程执行完成后再继续执行。CountDownLatch 利用 AQS 的 state 变量充当计数器(由 volatile 修饰并...

Java知音 325
上一篇: ThreadLocal 的原理及用法
下一篇: 线程的控制方法
JFS_Study
博客等级 码龄6年 363粉丝 359原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JFS_Study

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值