共享锁中:Semaphore 、CyclicBarrier 、CountDownLatch的区别是什么?

news2024/9/22 19:31:15

目录

下面是一个使用Semaphore实现共享锁的例子:

下面是一个使用CountDownLatch实现等待一组操作完成的例子:

下面是一个使用CyclicBarrier实现等待一组线程达到某个状态后再同时执行的例子:

结论1:

结论2:


下面是一个使用Semaphore实现共享锁的例子:

package cn.net.cdsz.ccb.test;

import java.util.concurrent.Semaphore;


public class test {

    private static Semaphore semaphore = new Semaphore(2);

    public static void main(String[] args) {
        Runnable task = () -> {
            try {
                semaphore.acquire();
                System.out.println(Thread.currentThread().getName() + " acquired semaphore");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                semaphore.release();
                System.out.println(Thread.currentThread().getName() + " released semaphore");
            }
        };

        new Thread(task, "Thread 1").start();
        new Thread(task, "Thread 2").start();
        new Thread(task, "Thread 3").start();
    }

}

在上面的代码中,创建了三个线程,它们都需要获取一个初始值为2的信号量。因为初始值为2,所以前两个线程可以同时获取信号量,而第三个线程需要等待前面两个线程释放信号量之后才能够获取它。运行程序可以看到,前两个线程同时获取到了信号量,并且在获取到信号量之后都阻塞了1秒钟。最后,它们释放了信号量,第三个线程才能够获取它。

下面是一个使用CountDownLatch实现等待一组操作完成的例子:

package cn.net.cdsz.ccb.test;


import java.util.concurrent.CountDownLatch;

public class test {

    public static void main(String[] args) throws InterruptedException {
        int n = 3;
        CountDownLatch latch = new CountDownLatch(n);
        Runnable task = () -> {
            try {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName() + " finished its work");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                latch.countDown();
            }
        };

        for (int i = 0; i < n; i++) {
            new Thread(task, "Thread " + i).start();
        }

        latch.await();
        System.out.println("All threads finished their work");
    }

}

在上面的代码中,创建了三个线程,它们都需要执行一些耗时的操作。在主线程中,通过CountDownLatch等待这三个线程执行完成后再继续执行。

CyclicBarrier用于等待一组线程达到某个状态后再同时执行。它通过维护一个计数器和一个栅栏状态来实现。计数器的初始值由构造函数设置。每个线程需要达到某个状态时,需要通过await()方法等待其他线程都达到这个状态,此时计数器的值就会减1。当计数器的值变为0时,所有线程就会被唤醒,同时继续执行。

下面是一个使用CyclicBarrier实现等待一组线程达到某个状态后再同时执行的例子:

package cn.net.cdsz.ccb.test;


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

public class test {

    public static void main(String[] args) {

            int numThreads = 3;
            CyclicBarrier barrier = new CyclicBarrier(numThreads);

            for (int i = 0; i < (numThreads+1); i++) {
                new Thread(() -> {
                    System.out.println(Thread.currentThread().getName() + " is waiting at the barrier.");
                    try {
                        barrier.await();
                        System.out.println(Thread.currentThread().getName() + " has crossed the barrier.");
                    } catch (InterruptedException | BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }).start();
            }
        }


}

我们创建了一个CyclicBarrier对象,并指定了需要等待的线程数量为3。然后我们创建了三个线程,并让它们执行一个任务:打印出自己正在等待栅栏,然后调用await()方法等待其他线程,最后再打印出自己已经通过栅栏。

当所有线程都调用了await()方法后,栅栏就会打开,所有线程就可以同时通过栅栏继续执行后续的代码了。

结论1:

在输出"Thread-3 has crossed the barrier."之后,第4个线程就已经执行完毕退出了,所以不会有"Thread-3 has finished."的输出。这里 CyclicBarrier  体现出跟 Semaphore 的区别,Semaphore 是继续等待,CyclicBarrier  是直接执行不再等待锁

结论2:

CyclicBarrier和CountDownLatch的区别在于,CyclicBarrier要求等待的线程数量是固定的,并且只有所有线程都调用了await()方法之后,才能继续执行后续的代码。而CountDownLatch则是一个计数器,可以任意地增加或减少计数器的值,并且只要计数器的值不为0,等待线程就会一直被阻塞

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

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

相关文章

JavaSE基础(一)—— Java环境搭建、IDEA、Java语言

【JavaSE基础回顾笔记】 JavaSE基础&#xff08;一&#xff09;—— Java环境搭建、IDEA、Java语言 JavaSE基础&#xff08;二&#xff09;—— Java语法、运算符、随机数 JavaSE基础&#xff08;三&#xff09;—— 分支、循环、控制关键字 JavaSE基础&#xff08;四&…

Opencv+Python笔记(六)图像的平滑处理

图像在获取、传输的过程中&#xff0c;可能会受到干扰的影响&#xff0c;会产生噪声&#xff0c;噪声是一种出错了的信号&#xff0c;噪声会造成图像粗糙。 图像平滑处理的目的是去除图像中的噪声和不必要的细节&#xff0c;使图像更加清晰和易于分析。常用的平滑滤波器包括高斯…

无感FOC

前言 一年多前就画好了FOC的板子&#xff0c;后面因为各种原因耽搁了&#xff0c;最近又重新捡起来&#xff0c;准备写一下程序&#xff0c;首先我们要做一下FOC的理论分析。 左右手定则 左手定则用于判断导线在磁场中受力的方向&#xff1a; 磁感线从左手手心流入&#xff0…

前++与后++的区别?反汇编底层刨析

目录 1.只&#xff0c;不赋值 2.和其他运算符的结合 1.后置&#xff08;i&#xff09; 2.前&#xff08;i&#xff09; 总结 1.只&#xff0c;不赋值 前置和后置无区别&#xff0c;效果一致&#xff0c;i -> ii1 反汇编语言内&#xff0c;对a和b的操作进行观察&#…

彻底卸载Anaconda和PyCharm详细教程

目录 一、卸载Anaconda 二、 卸载PyCharm 一、卸载Anaconda 1、在开始处打开Anaconda Prompt 2、打开后&#xff0c;输入conda install tqdm -f命令并按回车键 conda install tqdm -f 3、之后页面会出现一个WANNING&#xff0c;这个我们不用在意&#xff0c;然后会出现一个…

GitHub新手用法详解【适合新手入门-建议收藏!!!】

目录 什么是Github&#xff0c;为什么使用它&#xff1f; 一、GitHub账号的注册与登录 二、 gitbash安装详解 1.git bash的下载与安装 2.git常用命令 3. Git 和 GitHub 的绑定 1. 获取SSH keys 2.绑定ssh密钥 三、通过Git将代码提交到GitHub 1.克隆仓库 2.测试提交代码…

ClickHouse同步MySQL数据

目录 1 概述1.1 特点1.2 使用细则 2 案例实操2.1 MySQL 开启 binlog 和 GTID 模式2.2 准备 MySQL 表和数据2.3 开启 ClickHouse 物化引擎2.4 创建复制管道2.5 修改数据2.6 删除数据2.7 删除表 1 概述 MySQL 的用户群体很大&#xff0c;为了能够增强数据的实时性&#xff0c;很多…

通过response.body()返回的json报文,直接生成对应结构体,实现数据绑定

作者&#xff1a;非妃是公主 专栏&#xff1a;《Golang》 博客地址&#xff1a;https://blog.csdn.net/myf_666 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 文章目录 序一、解决办法二、相关测试代码1. json body…

Origin选取一定间隔的数据点并作图

有些时候我们发现用origin绘制的图数据点太密&#xff0c;抖动太剧烈&#xff1a; 所以我们最好是隔几个点采样一次&#xff0c;方法如下。 假如我们一共有五列数据&#xff0c;我们再扩充六列&#xff08;其中一列是放隔点采样的横坐标&#xff09;&#xff1a; 然后选中扩充…

Java企业级开发学习笔记(2.4)利用MyBatis实现条件查询

该文章主要为完成实训任务&#xff0c;详细实现过程及结果见【http://t.csdn.cn/AZM1g】 文章目录 一、创建学生映射器配置文件二、配置学生映射文件三、创建学生映射器接口四、测试学生映射器接口任务1. 查询女生记录任务2. 查询19岁的女生任务3. 查询姓吴的19岁女生任务4. 查…

css预处理器:less

1.css常见单位 绝对单位 只需要掌握px,国外in用得更多 相对单位 em em相对于自身的font-size,如果自身未定义,则相对于继承的父元素font-size rem rem可以做移动端的适配,依然很重要,如淘宝m站在使用;但是趋势是rem转vw rem是相对于html的font-size,html默认字体大小为1…

ROS学习第二十五节——rqt工具箱

1.安装 一般只要你安装的是desktop-full版本就会自带工具箱 如果需要安装可以以如下方式安装 $ sudo apt-get install ros-noetic-rqt $ sudo apt-get install ros-noetic-rqt-common-plugins2.启动 rqt的启动方式有两种: 方式1:rqt 方式2:rosrun rqt_gui rqt_gui 3.基本使…

知识图谱实战应用5-基于知识图谱的创建语义搜索功能

大家好&#xff0c;我是微学AI&#xff0c;今天给大家讲一下知识图谱实战应用5-基于知识图谱的创建语义搜索功能。基于知识图谱的语义搜索功能是一种能够理解用户意图、并根据语义关系在知识图谱中进行查询的搜索方式。相比于传统的文本搜索&#xff0c;它可以更准确地回答用户…

Ubuntu 23.04 正式发布

Ubuntu 23.04 “Lunar Lobster” 是 Ubuntu 操作系统的最新短期支持版本&#xff0c;该版本将获得 9 个月的支持&#xff0c;直到 2024 年 1 月。如果你需要长期支持&#xff0c;建议使用 Ubuntu 22.04 LTS 代替。 Linux 内核 Ubuntu 23.04 采用了新的 Linux 6.2 内核。 值得注…

PySide6/PyQT多线程的使用

前言 上一篇文章介绍了在PySide6中使用多线程去解决PySide6/PyQT的界面卡死问题&#xff0c;这次来具体介绍下多线程在使用上的一些细节。 本文尝试对以下两个问题进行解决&#xff1a; 对 PySide6/PyQT 多线程的使用不熟悉&#xff1b;在 PySide6/PyQT 的应用程序里有耗时任…

prompt的演变

随着功能的增加&#xff0c;提示工程的复杂性将不可避免地增加。在这里&#xff0c;我解释了如何将复杂性引入到提示工程的过程中。 静态prompt 如今&#xff0c;试验prompt和提示工程已司空见惯。通过创建和运行提示的过程&#xff0c;用户可以体验 LLM 的生成能力。 文本生…

STM32 学习笔记_4 GPIO:LED,蜂鸣器,按键,传感器的使用

GPIO 通用 IO General Purpose Input Output. 可配置为8种输入输出模式。通常0~3.3V&#xff0c;部分引脚允许 5V。 上面的虚线方框是输入模块&#xff0c;下面的是输出模块。 推挽输出是1输出高电平&#xff0c;0输出低电平。开漏输出正好相反&#xff0c;因此没有高电平驱…

10分钟了解人工智能(最通俗的语言)

最通俗的语言&#xff1a;15分钟了解人工智能&#xff1b;唯一优点&#xff0c;受众完全听懂 无人驾驶、智能家居、远程医疗……如今&#xff0c;人工智能(AI)技术已被广泛应用于金融、交通、医疗、安防、教育等领域&#xff0c;成为经济增长新动能 一 什么是人工智能 人工智能…

动态规划之-不同路径 II-滚动数组_20230421

DP动态规划之-滚动数组 前言 在学习 不同路径II 的动态规划过程中&#xff0c;从介绍资料中了解到 滚动数组可以进一步降低动态规划解空间的复杂度&#xff0c;更高效利用计算机的储存空间。动态规划中的滚动数组究竟能发挥哪些作用&#xff0c;在常规的动态规划中&#xff0…

REDIS02_RDB概述及作用、自动触发、手动触发、优势劣势、触发场景、配置项详解

文章目录 ①. RDB概述及作用②. RDB - 自动触发③. 手动触发 - save、bgsave④. RDB - 优势体现⑤. RDB - 劣势体现⑥. 哪些情况会触发RDB快照⑦. RDB优化配置项详解 ①. RDB概述及作用 ①. RDB概述:在指定的时间间隔,执行数据集的时间点快照 实现类似照片记录效果的方式,就是…