学用 CountDownLatch 与 CyclicBarrier

news2024/12/23 16:13:24

开篇即说结论,如果搞不清楚两者区别,那就无脑用 CountDownLatch,问题也不大(因为我也不是太懂)。

CountDownLatch

模拟了100米赛跑,10名选手已经准备就绪,只等裁判一声令下。当所有人都到达终点时,比赛结束。

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

/**
 * 模拟了100米赛跑,10名选手已经准备就绪,只等裁判一声令下。当所有人都到达终点时,比赛结束。
 * <a href="https://www.cnblogs.com/liuchao102/p/4383894.html">...</a>
 *
 * @author liuchao
 */
public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        //10名运动员
        final CountDownLatch count = new CountDownLatch(10);

        //java的线程池
        final ExecutorService executorService = Executors.newFixedThreadPool(5);

        for (int index = 1; index <= 10; index++) {
            final int number = index;

            executorService.submit(() -> {
                try {
                    Thread.sleep((long) (Math.random() * 10000));
                    System.out.println(number + ": arrived");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    count.countDown();// 运动员到达终点,count数减一
                }
            });
        }


        System.out.println("Game Started");
        //等待count数变为0,否则会一直处于等待状态,游戏就没法结束了
        count.await();
        System.out.println("Game Over");
        //关掉线程池
        executorService.shutdown();
    }
}

运行结果:

在这里插入图片描述

CyclicBarrier

继续还是这10个人,这次没裁判。规定10个人只要都跑到终点了,大家可以喝啤酒。但是,只要有一个人没到终点,就不能喝。 这里也没有要求大家要同时起跑(当然也可以,加 latch)

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierDemo {
    public static void main(String[] args) {
        final int count = 5;
        final CyclicBarrier barrier = new CyclicBarrier(count, () -> System.out.println("drink beer!"));

        // they do not have to start at the same time...
        for (int i = 0; i < count; i++)
            new Thread(new Worker(i, barrier)).start();
    }
}

class Worker implements Runnable {
    final int id;
    final CyclicBarrier barrier;

    public Worker(final int id, final CyclicBarrier barrier) {
        this.id = id;
        this.barrier = barrier;
    }

    @Override
    public void run() {
        try {
            System.out.println(id + "starts to run !");
            Thread.sleep((long) (Math.random() * 10000));
            System.out.println(id + "arrived !");
            barrier.await();
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

运行结果:
在这里插入图片描述

总结

  • CountDownLatch 强调一个线程等多个线程完成某件事情。CyclicBarrier 是多个线程互等,等大家都完成。
  • CountDownLatch 很明显是可以不限制等待线程的数量,而会限制 countDown的操作数;CyclicBarrier 会限制等待线程的数量
  • 写法当然不一样,看看下面的伪代码
class CountDownLatch{
    CountDownLatch cd = new CountDownLatch(5);
    main(){
        启动5个线程。。。
        cd.await(); //让当前线程休眠,
        执行代码... (该代码不会立即执行,等待5个线程执行完成后,当前线程会被唤醒,继续执行后面的代码)
    }

    class Th extends Thread{
        public void run() {
            执行代码...
            cd.countDown(); //报告CountDownLatch 当前线程已经到位
            执行代码...(该代码不会因为countDown()而阻塞,countDown()没有阻塞效果)    

        }
    }

}

// 没有指定 构造线程的barrier伪代码
class CyclicBarrier{
    CyclicBarrier cd = new CyclicBarrier(5);
    main(){
        启动5个线程。。。
        执行代码...; //该代码会被立即执行
    }

    class Th extends Thread{
        public void run() {
            执行代码...
            cb.await(); //barrier参与量+1,并且当前线程休眠
            执行代码...(该代码不会立即执行,只有等待指定的5个线程集合了后,该代码才会继续执行)    
        }
    }

}

// 指定 构造线程的barrier伪代码
class CyclicBarrier{
    CyclicBarrier cd = new CyclicBarrier(5,runable);
    main(){
        启动5个线程。。。
        执行代码...; //该代码会被立即执行
    }

    class Th extends Thread{
        public void run() {
            执行代码...
            cb.await(); //barrier参与量+1,并且当前线程休眠
            执行代码...(该代码不会立即执行,只有等待指定的5个线程集合了后,会启动构造传入的runable线程代码,该线程结束后(所有等待的线程才能被唤醒),该代码才会继续执行)   
        }
    }

}

参见

  • CountDownLatch与CyclicBarrier 通熟易懂
  • CyclicBarrier正确的使用方法和错误的使用方法
  • Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
  • 多线程并发之CyclicBarrier(栅栏)使用详解
  • 关于CyclicBarrier与CountDownLatch的源码比较-CountDownLatch 使用场景
  • [Java7并发编程实战手册]3.5 在集合点的同步CyclicBarrier循环barrier
  • Java CyclicBarrier vs CountDownLatch

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

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

相关文章

R3LIVE源码解析(7) — R3LIVE中LiDAR_front_end.cpp文件

目录 1 LiDAR_front_end.cpp简介 2 LiDAR_front_end.cpp程序解析 1 LiDAR_front_end.cpp简介 激光点云首先在LiDAR_front_end节点中提取特征点&#xff0c;将处理完的信息通过/laser_cloud_flat完成节点的发送出去&#xff0c;与FAST-LIO2相同R3LIVE也只用到了面特征作为ESI…

在windows上配置ninja环境

ninja使用并行任务来编译工程&#xff0c;比cmake编译快了一个数量级&#xff0c;是谷歌在2010年为了提高cmake的编译速度而开发一款编译工具。下面介绍在windows上配置ninja环境。 1 下载ninja ninja官网地址&#xff1a; https://github.com/ninja-build/ninja/releases   …

【OpenCV入门】第七部分——图像的几何变换

文章结构 缩放dsize参数实现缩放fx参数和fy参数实现缩放 翻转仿射变换平移旋转倾斜 透视cmath模块 缩放 通过resize()方法可以随意更改图像的大小比例&#xff1a; dst cv2.resize(src, dsize, fx, fy, interpolation)src&#xff1a; 原始图像dsize&#xff1a; 输出图像的…

Leetcode---360周赛

题目列表 2833. 距离原点最远的点 2834. 找出美丽数组的最小和 2835. 使子序列的和等于目标的最少操作次数 2836. 在传球游戏中最大化函数值 一、距离原点最远的点 这题主要是理解题意&#xff0c;遇到L往左走&#xff0c;遇到R往右走&#xff0c;遇到_左右都可以走&#x…

bazel外部依赖管理

前面我们主要分析了基于 Action 的增量构建&#xff0c;缓存和远程执行机制。现在让我们看看 Bazel 是如何管理外部依赖的。 大部分项目都没法避免引入第三方的依赖项。构建系统通常提供了下载第三方依赖的能力。为了避免重复下载&#xff0c;Bazel 要求在声明外部依赖的时候&…

美客多(mercadolibre)测评下单技术(养号环境搭建详解)

MercadoLibre&#xff08;美客多&#xff09;是拉丁美洲的一个网购平台。该公司为其客户提供电子商务交易的购买&#xff0c;出售&#xff0c;支付和收集机制。目前全球第十大电商市场——巴西是MercadoLibre的主要市场&#xff0c;占据近60%的平台营收&#xff0c;接着是阿根廷…

关于购买AirPods,现在是否为最佳时机?

我们不需要解释你为什么想要AirPods。苹果对真正的无线耳机的采用彻底改变了市场&#xff0c;并从那时起大量销售。你总是在记者、同事和名人的耳朵里看到它们——尤其是在我们这个远程工作和Zoom会议的时代。 真正的问题是&#xff0c;你应该现在就买一个&#xff0c;还是在几…

2024年java面试--多线程(1)

系列文章目录 2024年java面试&#xff08;一&#xff09;–spring篇2024年java面试&#xff08;二&#xff09;–spring篇2024年java面试&#xff08;三&#xff09;–spring篇2024年java面试&#xff08;四&#xff09;–spring篇 文章目录 系列文章目录线程调度线程五种状态…

spring boot项目生成容器并运行

一个安静的周末&#xff0c;shigen又睡懒觉了&#xff0c;上次说的拖延症的惩罚来了&#xff1a;早晚各100个健腹轮练习&#xff0c;早上的已经完成了。今天的文章来的有点晚&#xff0c;但是依旧保持质量。 springboot项目生成容器并运行 背景 将springboot项目打包成jar包&…

2021年03月 C/C++(六级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;生日相同 2.0 在一个有180人的大班级中&#xff0c;存在两个人生日相同的概率非常大&#xff0c;现给出每个学生的名字&#xff0c;出生月日。试找出所有生日相同的学生。 时间限制&#xff1a;1000 内存限制&#xff1a;65536 输入 第一行为整数n&#xff0c…

Linux系统中u-boot启动流程分析(详解)

大家好&#xff0c;我是ST小智&#xff0c;今天给大家分享一下&#xff0c;u-boot的启动流程。 今天给大家全面的分析一下u-boot启动流程。整理这篇文章花费时间较长&#xff0c;中间很长时间未更新&#xff0c;希望这篇文章对大家有所帮助。 本章主要是详细的分析一下uboot的…

框架分析(8)-React Native

框架分析&#xff08;8&#xff09;-React Native 专栏介绍React Native特性和优势跨平台开发&#xff1a;热更新原生性能组件化开发第三方库支持社区支持 限制和挑战性能问题第三方库兼容性学习曲线 总结 专栏介绍 link 主要对目前市面上常见的框架进行分析和总结&#xff0c…

Node基础and包管理工具

Node基础 fs 模块 fs 全称为 file system&#xff0c;称之为 文件系统&#xff0c;是 Node.js 中的 内置模块&#xff0c;可以对计算机中的磁盘进行操作。 本章节会介绍如下几个操作&#xff1a; 1. 文件写入 2. 文件读取 3. 文件移动与重命名 4. 文件删除 5. 文件夹操作 6. …

安圭拉变成AI领域的数字金矿?

这个小小的岛国今年的域名销售额可能达到其GDP的10%&#xff01; 安圭拉a小小的英国岛屿领土在加勒比海地区&#xff0c;由于其“可再生能源”&#xff0c;今年可能带来高达3000万美元的收入。ai”域名&#xff0c;报告彭博在周四发表的一篇文章中说。在过去的一年里&#xff0…

应届生面试指南:如何在缺乏经验的情况下脱颖而出

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

IMU姿态计算

总述 IMU即惯性测量单元&#xff0c;主要用于对机体的加速度与角速度的测算&#xff0c;使用场景很多&#xff0c;例如: 平衡车、惯性导航等等 姿态 姿态角&#xff08;Euler angles&#xff09;是用于描述物体在三维空间中的旋转姿态的一种表示方法。它由三个角度组成&…

微机原理 || 第3次测试:第八章-常用接口芯片82558253(测试题+手写解析)

&#xff08;一&#xff09;知识点总结 一直没有学明白8253和8255芯片&#xff0c;觉得后面难&#xff0c;其实看懂后&#xff0c;就是照着表格去对应填写&#xff0c; 知道地址怎么回事就没问题哒~ 相信你&#x1f618; 一、8255芯片&#xff08;不是偷懒&#xff0c;真的就…

PMD代码检查:避免抛出原始的异常类型(AvoidThrowingRawExceptionTypes)

https://docs.pmd-code.org/pmd-doc-6.55.0/pmd_rules_java_design.html#avoidthrowingrawexceptiontypes 避免抛出RuntimeException、Throwable、Exception、Error这样原始的异常类型&#xff0c;而应该抛出它们的子类。 例如下面的使用方法PMD检查报违反项&#xff1a; 在…

动态规划之连续乘积最大子数组 连续和最大子数组

一. 连续和最大子数组 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,…

23062day6

作业&#xff1a;将dict.txt导入到数据库中。 方法1&#xff1a;创建shell脚本&#xff0c; 调用指令创建数据库和表格&#xff0c;使用循环在循环中用数组存储dict.txt的内容并插入表格中。 方法2&#xff1a;在终端创建数据库和表格&#xff0c;将dict.txt中的内容手动输入…