多线程之CountDownLatch和CyclicBarrier

多线程同步计数器CountDownLatch,CyclicBarrier,Semaphore 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。CountDownLatch是一个同步工具类,它允许一个或多个线程等待其他线程一系列操作的完成。我们来看两个示例@Test// 这里只有一个计数器,子线程都要等待主线程释放这个计数器才会开始执行,子任务等核心任务i 阅读详情

一、倒计时CountDownLatch

CountDownLatch是一个非常实用的多线程控制工具类,称之为“倒计时器”,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。

举了例子:

我们知道的集齐七颗龙珠就可以召唤神龙,那我们就一起召唤一下,下边我需要派7个人(7个线程)去分别去找这7颗不同的龙珠,每个人找到之后回来告诉我还需要等待的龙珠个数减1个,那么当全部的人都找到龙珠之后,那么我就可以召唤神龙了。

示例代码:

public class CountDownLatchTest {

    private static final int THREAD_MAX_NUM = 7;

    private static CountDownLatch countDownLatch = new CountDownLatch(THREAD_MAX_NUM);

    private static Random random = new Random();

    public static void main(String[] args) throws InterruptedException {

        for (int i = 1; i <= THREAD_MAX_NUM; i++) {
            int index = i;

            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        // 模拟寻找第index颗龙珠所消耗的时间
                        Thread.sleep(random.nextInt(3000));
                        System.out.println("第" + index + "颗龙珠已经找到了");

                        // 计数器减1
                        countDownLatch.countDown();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();;
        }

        // 开始启动子线程后,主线程等待
        countDownLatch.await();

        // 等到子线程都执行完,唤醒主线程
        System.out.println("集齐七颗龙珠,召唤神龙!");
    }
}

执行结果:

第3颗龙珠已经找到了
第6颗龙珠已经找到了
第7颗龙珠已经找到了
第5颗龙珠已经找到了
第2颗龙珠已经找到了
第1颗龙珠已经找到了
第4颗龙珠已经找到了
集齐七颗龙珠,召唤神龙!

知识点:

(1)CountDownLatch的构造函数,参数表示需要等待执行完毕的线程数量

private static CountDownLatch countDownLatch = new CountDownLatch(7);

(2)在每一个线程执行完毕之后,都需要执行countDownLatch.countDown()方法,不然计数器就不会准确;

(3)只有所有的线程执行完毕之后,才会执行countDownLatch.await()之后的代码;

(4)可以看出上述代码中CountDownLatch 阻塞的是主线程

而如果不使用CountDownLatch,结果可能是这样的:

第3颗龙珠已经找到了
第6颗龙珠已经找到了
第7颗龙珠已经找到了
集齐七颗龙珠,召唤神龙!
第5颗龙珠已经找到了
第2颗龙珠已经找到了
第1颗龙珠已经找到了
第4颗龙珠已经找到了

官方介绍:
CountDownLatch是在java1.5被引入的,它存在于java.util.concurrent包下。CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。

CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

二、CountDownLatch在实时系统中的使用场景

让我们尝试罗列出在Java实时系统中CountDownLatch都有哪些使用场景。我所罗列的都是我所能想到的。如果你有别的可能的使用方法,请在留言里列出来,这样会帮助到大家。

(1)实现最大的并行性:有时我们想同时启动多个线程,实现最大程度的并行性。例如,我们想测试一个单例类。如果我们创建一个初始计数为1的CountDownLatch,并让所有线程都在这个锁上等待,那么我们可以很轻松地完成测试。我们只需调用 一次countDown()方法就可以让所有的等待线程同时恢复执行。

(2)开始执行前等待n个线程完成各自任务:例如应用程序启动类要确保在处理用户请求前,所有N个外部系统已经启动和运行了。

(3)死锁检测:一个非常方便的使用场景是,你可以使用n个线程访问共享资源,在每次测试阶段的线程数目是不同的,并尝试产生死锁。

三、循环屏障CyclicBarrier

CyclicBarrier是另一种多线程并发控制使用工具,和CountDownLatch非常类似,他也可以实现线程间的计数等待,但他的功能要比CountDownLatch更加强大一些。

CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。

CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。

CyclicBarrier强调的是n个线程,大家相互等待,只要有一个没完成,所有人都得等着。

还接着上述“集齐七颗龙珠!召唤神龙”的故事。召唤神龙,需要7个法师去寻找龙珠,但这7个法师并不是一下子就能号召起来的,所以要等待召集齐7个法师,然后在秋名山顶烧香拜佛为这7位法师送行,让他们同时出发,前往不同的地方寻找龙珠(敲黑板:这是第一个屏障点),在这七位法师临行时约定找到龙珠之后还回到这个地方等待其他法师找到龙珠之后一起去见我。几年之后,第一个法师回来了,然后等待其他的法师。。。最后所有的法师全部到齐(敲黑板:这是第一个屏障点),然后组队来找我召唤神龙。

示例代码:

public class CyclicBarrierTest {

    private static final int THREAD_MAX_NUM = 7;

    private static Random random = new Random();

    public static void main(String[] args) {

        // 设置屏障
        CyclicBarrier cyclicBarrier = new CyclicBarrier(THREAD_MAX_NUM, new Runnable() {
            @Override
            public void run() {
                System.out.println("法师已全部准备好,开始出发!");
                // 开始收集龙珠
                collectDragonBalls();
            }
        });

        for (int i = 1; i <= THREAD_MAX_NUM; i++) {
            final int index = i;
            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        // 模拟法师到达所消耗的时间
                        Thread.sleep(random.nextInt(3000));

                        System.out.println("第"+index+"号法师已准备好!");

                        // 进行阻塞,并发出信号
                        cyclicBarrier.await();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }).start();
        }
    }

    public static void collectDragonBalls(){
        // 设置屏障
        CyclicBarrier cyclicBarrier = new CyclicBarrier(THREAD_MAX_NUM, new Runnable() {
            @Override
            public void run() {
                System.out.println("七颗龙珠已集齐,开始召唤神龙!");
            }
        });
        for (int i = 1; i <= THREAD_MAX_NUM; i++) {
            final int index = i;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 模拟收集龙珠所消耗的时间
                        Thread.sleep(random.nextInt(3000));

                        System.out.println("第"+index+"颗龙珠已找到!");

                        // 进行阻塞,并发出信号
                        cyclicBarrier.await();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}

执行结果:

第2号法师已准备好!
第7号法师已准备好!
第4号法师已准备好!
第3号法师已准备好!
第5号法师已准备好!
第1号法师已准备好!
第6号法师已准备好!
法师已全部准备好,开始出发!
第2颗龙珠已找到!
第7颗龙珠已找到!
第1颗龙珠已找到!
第3颗龙珠已找到!
第6颗龙珠已找到!
第5颗龙珠已找到!
第4颗龙珠已找到!
七颗龙珠已集齐,开始召唤神龙!

代码中设置了两个屏障点,第一个用于召集7个法师,等7个法师召集完后,在设置在一个屏障点,7位法师去寻找龙珠,然后召唤神龙,中间有个嵌套的关系!

上述的例子,大致说了一下屏障,因为设置了两个屏障,并没有演示上述说的可循环使用(Cyclic)的屏障(Barrier) 中的可循环使用(Cyclic)。
查看CyclicBarrier.reset() 可知,可以使CyclicBarrier回到最初始的状态,由于使用的相对较少,这里不再演示。

四、CyclicBarrier和CountDownLatch的区别

(1)CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次。

(2)CyclicBarrier还提供其他有用的方法,比如getNumberWaiting()可以获得CyclicBarrier阻塞的线程数量。isBroken方法用来知道阻塞的线程是否被中断。

(3)CountDownLatch会阻塞主线程,CyclicBarrier不会阻塞主线程,只会阻塞子线程。


转载:

《两种常用的线程计数器CountDownLatch和循环屏障CyclicBarrier》

OPC DCOM详细配置方法 - 不关防火墙不换登陆用户 1. 前言   OPC DCOM的设置是实现跨网络OPC通信的基础,现有的一些OPC DCOM配置教程虽然讲解了如何配置DCOM,但没有讲清楚为什么要这么做,而且各个教程涉及的配置方法也不尽相同。   为了彻底搞清楚OPC DCOM的配置过程,我重新做了两台机器的系统,一台是Windows 7 32位,一台是Windows 10 64位,并且重零开始完整的测试了正常运行OPC DCOM所需的最少的... 阅读详情

相关推荐

String+CytoScape构建PPI网络

1.下载CytoScape Cytoscape是一款专业强大好用的物生信息分析软件,主要达用于专业的研究人员使用,软件主要适用于整合模块化网络和生物科学联系网络图的绘制,支持多种文件格式,导入后就可以直接进行编辑或者分析等操作了,除此之外,软件还提供了强大的编辑工具,支持添加相应的注释信息,软件基于java环境组件打造。 下载地址:https://cytoscape.org/ 因为软件基于java...

xiaobai1_1的博客 1万+

Java多线程: CyclicBarrier的使用

一. CyclicBarrier使用的场景 现在需要并行的执行一组任务,每一个任务都需要分阶段完成,并且任务不能抢先执行,当在某个阶段完成的时间过早时,需要等待其它任务全部完成这个阶段的工作后,才能一起向下一个阶段跃进。它与CountDownLatch很类似,只不过CountDownLatch只能触发一次(控制一次任务的阶段暂停),而CyclicBarrier如其名,可以触发...

爱喝咖啡的程序员的博客 362

PaddleOCR实战:如何在CentOS 8.5上搭建高性能OCR识别环境

本文详细介绍了在CentOS 8.5系统上搭建高性能PaddleOCR识别环境的完整指南。从系统环境准备、PaddlePaddle框架部署到PaddleOCR的定制化安装与性能优化,提供了针对生产环境的解决方案,包括GPU/CPU环境配置、内核参数调优及常见问题排查,帮助用户实现高效OCR识别。

weixin_29223603的博客 349

简析CountDownLatch、CyclicBarrier、Semaphore

一、CountDownLatch 1、定义 用来协调线程间的同步,起到线程之间的通信作用的工具类。 它能够使一个线程再等待一些线程完成各自工作后,再继续执行。使用一个计数器实现,计数器初始值为线程的数量,当每一个线程完成自己任务后,计数器的值会减1,当计数器的值为0时,表示所有的线程都完成了任务,然后CountDownLatch上等待的线程就可以恢复执行任务。 2、应用场景 某一个线程再开始运行前等待n个线程执行完毕,如启动一个服务时,主线程需要等待多个组件加载完毕,之后再执行...

heyi12345的专栏 544

DEAP数据集实战:用PyTorch搭建DNN/CNN脑电情绪识别模型(附完整代码)

本文详细介绍了如何使用PyTorch搭建DNN和CNN模型对DEAP数据集进行脑电情绪识别。从数据预处理到模型架构设计,再到训练优化和部署,提供了完整的实战指南和代码示例,帮助研究者快速掌握脑电信号识别技术。

k8l9m0n的博客 392

从零构建EtherCAT从站:SSC工具配置与TwinCAT3 PDO/SDO调试实战

本文详细介绍了从零构建EtherCAT从站的完整流程,重点讲解SSC工具配置与TwinCAT3 PDO/SDO调试实战。通过解析EtherCAT通信机制、PDO与SDO的核心概念,提供SSC工具配置技巧、XML文件生成与校验方法,以及TwinCAT3环境下的调试经验,帮助开发者高效完成EtherCAT从站开发与优化。

weixin_42520573的博客 339

CountDownLatch与CyclicBarrier

CountDownLatch与CyclicBarrier被设计用来进行一组线程协作工作,完成一个或多个阶段的任务,二者有什么区别与联系呢? [b][size=large]1、CountDownLatch[/size][/b] 这个用来设置一个屏障点,这个屏障点有好几把锁,每把锁都被开开之后,主线程才能继续往下面执行。 一个李子:3个人去骑行,约定到某个地方集合吃饭,全部到之后老板才上菜。 ...

ch_space的专栏 228

TekTronix 高速信号完整性基础以及测试方法分析

如果信号速率比较高,则CTLE与FFE都无法满足要求,尤其是大于10G,比如USB3.1Gen2 10Gbps,PCIe4.0 16Gbps,这些场合都会采用DFE均衡,DFE的优点是,它既可以识别当前比特,并且可以判决前面的n个比特(Tap的阶数越高,看到的前面的比特数越多),根据前面比特的变化来计算出要处理当前比特所要变化的幅度,来补偿由于前面比特变化所引起的信号幅度的变化。10G以下,一般都不太关心这个串扰,高于10G的信号,会发现相互之间的串扰越来越明显,已经成为引起误码的重要的原因之一。

weixin_45365488的博客 4141

CountDownLatch与CyclicBarrier基本原理及区别

一、CountDownLatch测试demo 注:這裏調用countDownLatch.await()的綫程稱之爲主綫程 public class CountDownLatchTest { private static final int NUM=3 ; public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new...

MJ的博客 1665

基于STM32F103C8T6的智能蓝牙手环系统设计与实现

摘要:本文设计并实现了一款基于STM32F103C8T6单片机的智能蓝牙手环系统。该系统集成了ADXL345加速度计、DS18B20温度传感器、plusesennor心率模块和BT06蓝牙模块,实现了心率(±2bpm)、体温(±0.5℃)、步数(±3%)等健康数据的实时监测与显示。通过OLED屏提供人机交互界面,支持蓝牙APP远程控制,具备自动步数清零、异常提醒等功能。测试表明系统各项功能均达到设计要求,响应时间0.1-0.5秒,心率检测准确率98%,体温检测准确率99%,功耗50mA(工作)/10mA(待

3254968421的博客 205

向华为学习——IPD流程体系之IPD术语

《IPD体系核心概念与业务术语解析》摘要: IPD(集成产品开发)是一种以市场为导向的结构化产品开发管理模式,通过跨部门协作、异步开发、CBB(通用构建模块)和管道管理等手段,实现产品全生命周期高效管理。体系包含七大核心要素:跨部门团队(如IPMT决策层、PDT执行层)、结构化流程(分阶段评审)、端到端项目管理(WBS分级计划)、客户需求分析、投资组合优化及质量管控(TR技术评审)。各业务领域术语涵盖财务(NPV、IRR)、开发(需求分解、基线化)、制造(可制造性设计)、采购(Sourcing团队)及市场(

cdfunlove的博客 480

计数器:CountDownLatch,循环栅栏:CyclicBarrier

// 创建2个线程的线程池 Executor executor = Executors.newFixedThreadPool(2); while(存在未对账订单){ // 计数器初始化为2 CountDownLatch latch = new CountDownLatch(2); // 查询未对账订...

ityqing的博客 1292

全网详细解决:无法将 “xxx” 项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次

全网详细解决:无法将 “xxx” 项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。

念兮为美 5万+

Java多线程场景下 CountDownLatch、CyclicBarrier

在Java多线程编程中,CountDownLatch、Semaphore和CyclicBarrier是关键的同步工具,各自具有独特的功能和应用场景。CountDownLatch允许一个或多个线程等待其他线程完成特定操作,通过递减计数器实现线程的精准等待。CyclicBarrier则为一组线程提供一个同步点,使它们相互等待,直到所有线程都到达屏障点后继续执行。通过运动场比赛的代码示例,展示了CyclicBarrier用于同步运动员起跑,CountDownLatch用于统计比赛结束的场景。

技术人宝哥 1256

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

lwip-2.0.3

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

JAVA多线程之CountDownLatch和CyclicBarrier

1 CountDownLatch (1)countDownLatch等待指定数量线程结束后,进行下一步; (2)countDownLatch构造函数初始化一个volatile变量,countDown()方法,使用了CAS,和AutomicInteger的增减方法相同; (3)await方法阻塞当前线程,直到getCount值为0,如果不调用countDown方法,getCount的值部位0,那...

weixin_39722651的博客 210

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

java多线程 CountDownLatch、CyclicBarrier和Semaphore

java多线程 CountDownLatch、CyclicBarrier和Semaphore

靖节先生的博客 285

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【Java多线程编程】:CyclicBarrier和CountDownLatch比较

文章目录1. 前言2. 差异性对比3. CountDownLatch用法3.1. CountDownLatch类的简单介绍3.2. CountDownLatch应用示例4. CyclicBarrier用法4.1. CyclicBarrier类的简单介绍4.2. CyclicBarrier应用示例 1. 前言 CyclicBarrier和CountDownLatch都是同步辅助类,它们在Java1....

hxcaifly的博客 404

多线程-CountDownLatch和CyclicBarrier使用

CountDownLatch latch = new CountDownLatch(6): 6:代表初始扣除点,为零则继续执行,可以自行设置 latch.countDown():表示扣除点-1 latch.await():阻塞线程,直至我们的扣除点为零才会唤醒线程,这里使用需要注意 /** *类说明:演示CountDownLatch,模拟5个初始化的线程,6个扣除点(注:一个线程可以执...

qq_42709262的博客 192

多线程CountDownLatch,CyclicBarrier简单理解

public class CountDownLatchFunc1 implements Runnable { public CountDownLatch c; public CountDownLatchFunc1(CountDownLatch c) { this.c = c; } @Override public void run() ...

平常心丷的博客 193

过什么情人节,过来学习多线程计数器CountDownLatch和CyclicBarrier

多线程开发——多线程计数器

Java之路艰难,要以高内聚低耦合的目标去设计 946

多线程同步器CountDownLatch、CyclicBarrier和Semaphore

一、简要概述1、CountDownLatch(不可重复使用,一次性的) 当一个或多个线程需要等待指定数目的时间发生(允许线程集等待直到计数器减为0,否则会一直阻塞在调用latch.await()处) CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。 当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭...

l1394049664的博客 908

Java多线程——同步器 Semaphore、 CountDownLatch、 CyclicBarrier 、Exchanger

同步器 一般与一组线程对象使用,它维护一个状态,根据它的状态,它让一个线程通过或强迫线程等待。1.Semaphore是一个经典的并发工具,通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。class Pool { private static final int MAX_AVAILABLE = 100;//许可数 private final Semaphore available...

渔夫 2042

多线程工具类:CountDownLatch、CyclicBarrier、Semaphore、LockSupport

◆ CountDownLatch ◆ 假如有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以。 比如你想要买套房子,但是呢你现在手上没有钱。你得等这个月工资发了、然后年终奖发了、然后朋友借你得钱还给你了、然后再给朋友借一部分才可以买,这种场景你就可以使用CountDownLatch。 CountDownLatch是JDK为我们提供的一个计数器,它的操作是原子操作,同一时间只能有一个...

Java学习录 516

Java:多线程等待所有线程结束(CountDownLatch/CyclicBarrier)

<!-- pre.sample {margin-top:15px; margin-bottom:15px; padding:6px 10px; border:1px solid rgb(204,204,204); font-size:12px; font-family:Consolas,'Liberation Mono',Courier,monospace; back

混迹于移动互联网和手机行业 2655

多线程之并发类CountDownLatch、CyclicBarrier和Semaphor的使用

CountDownLatch 并发类CountDownLatch是什么? CountDownLatch:一个或多个线程等待其他线程完成操作。 什么情况下使用? 某一个动作需要等待其它线程完成后才会触发。 举个栗子,一个班上50个人,考完试之后需要计算全班同学的总成绩,这种情况使用CountDownLatch并发类就最合适了,每一个人的成绩等于一个线程,需要等待50个线程执行完之后才能执行最后...

qq_37212210的博客 403

CompletableFuture,CyclicBarrier,CountDownLatch多线程同步编排原理。

使用控制线程阻塞通过的 CAS 操作原子更新状态当计数器归零时触发的级联唤醒利用 CLH 队列和 PROPAGATE 状态保证唤醒完整性这种设计在保证线程安全的前提下,最大程度减少了同步开销,特别是当等待线程数量较大时,级联唤醒机制相比传统唤醒方式有显著性能优势。

weixin_45762066的博客 497
上一篇: 使用支付宝沙箱实现扫码支付
下一篇: 并发编程之重入锁和读写锁
章 鱼
博客等级 码龄10年 203粉丝 105原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值