当前位置: 首页 > news >正文

CountDownLatch、CyclicBarrier、Semaphore 的原理以及实例总结

文章目录

  • CountDownLatch、CyclicBarrier、Semaphore 的原理以及实例总结
    • 一、CountDownLatch
    • 二、CyclicBarrier
    • 三、Semaphore
    • 总结

CountDownLatch、CyclicBarrier、Semaphore 的原理以及实例总结

在Java多线程编程中,有三种常见的同步工具类:CountDownLatch、CyclicBarrier、Semaphore。这些工具类使得我们可以在多个线程之间进行协调,实现更高效的并发处理。本文将对它们的原理和实例进行分析总结。

一、CountDownLatch

CountDownLatch是一个计数器类,用来控制线程等待其他线程执行完毕再继续执行。这个类通常用于主线程等待多个子线程完成任务后再进行下一步操作。CountDownLatch的实现基于AQS(AbstractQueuedSynchronizer),使用了共享锁的方式。

CountDownLatch的使用思路比较简单,首先创建一个CountDownLatch对象,并把需要等待的线程数量传入CountDownLatch的构造方法。然后在每个子线程完成任务时通过countDown()方法来减少计数器的值。当计数器变为0时,await()方法会返回,主线程就可以继续执行下一步操作。

下面是一个简单的示例代码:

public class CountDownLatchDemo {public static void main(String[] args) throws InterruptedException {int threadCount = 5;CountDownLatch countDownLatch = new CountDownLatch(threadCount);for (int i = 0; i < threadCount ; i++) {new Thread(() -> {try {Thread.sleep(1000L);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 执行完毕");countDownLatch.countDown();}).start();}countDownLatch.await();System.out.println("所有线程执行完毕");}
}

以上代码中,我们创建了一个CountDownLatch对象,并传入需要等待的线程数量。然后通过for循环创建了5个子线程,每个子线程都会睡眠1秒钟,模拟执行任务。当每个子线程完成任务后,调用countDown()方法来减少计数器的值。最后在主线程中调用await()方法来等待所有子线程完成任务。

二、CyclicBarrier

CyclicBarrier也是一个很有用的同步工具类,它可以让一组线程到达某个屏障(也可以理解为关卡)时被阻塞,直到所有线程都到达该屏障时才能继续执行。CyclicBarrier和CountDownLatch的区别在于,CountDownLatch只能使用一次,而CyclicBarrier可以重复使用。

CyclicBarrier的实现也是基于AQS(AbstractQueuedSynchronizer),但是使用了独占锁的方式。CyclicBarrier的使用思路也比较简单,首先创建一个CyclicBarrier对象,并把需要等待的线程数量和到达该屏障时需要执行的动作(可选)传入CyclicBarrier的构造方法。当所有线程到达该屏障时,CyclicBarrier会自动调用之前设置的动作(如果有),然后所有线程就可以继续执行接下来的操作。

下面是一个简单的示例代码:

public class CyclicBarrierDemo {public static void main(String[] args) throws InterruptedException, BrokenBarrierException {int threadCount = 3;CyclicBarrier cyclicBarrier = new CyclicBarrier(threadCount, () -> System.out.println("所有线程到达屏障"));for (int i = 0; i < threadCount ; i++) {new Thread(() -> {try {Thread.sleep(1000L);System.out.println(Thread.currentThread().getName() + " 到达屏障");cyclicBarrier.await();System.out.println(Thread.currentThread().getName() + " 继续执行");} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}).start();}}
}

以上代码中,我们创建了一个CyclicBarrier对象,并传入需要等待的线程数量和到达屏障时需要执行的动作。然后通过for循环创建了3个子线程,每个子线程都会睡眠1秒钟,并在到达屏障时调用await()方法。当所有子线程都到达屏障时,CyclicBarrier会自动执行之前设置的动作(输出“所有线程到达屏障”),然后所有线程就可以继续执行接下来的操作。

三、Semaphore

Semaphore是另一种常见的同步工具类,它可以限制同时访问某个共享资源的线程数量。Semaphore的实现也是基于AQS(AbstractQueuedSynchronizer),使用了共享锁的方式。

Semaphore的使用思路比较简单,首先创建一个Semaphore对象,并把该共享资源的数量传入Semaphore的构造方法。然后在每个需要访问该共享资源的线程中调用acquire()方法来获取访问权限,在使用完共享资源后再调用release()方法来释放访问权限。

下面是一个简单的示例代码:

public class SemaphoreDemo {public static void main(String[] args) {int threadCount = 10;Semaphore semaphore = new Semaphore(2);for (int i = 0; i < threadCount ; i++) {new Thread(() -> {try {semaphore.acquire();System.out.println(Thread.currentThread().getName() + " 获取访问权限");Thread.sleep(1000L);} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();System.out.println(Thread.currentThread().getName() + " 释放访问权限");}}).start();}}
}

以上代码中,我们创建了一个Semaphore对象,并传入该共享资源的数量。然后通过for循环创建了10个子线程,每个子线程需要获取访问权限才能执行,如果访问权限已满则需要等待其他线程释放访问权限。当使用完共享资源后,子线程需要调用release()方法来释放访问权限。

总结

本文分析了CountDownLatch、CyclicBarrier、Semaphore三种常见的同步工具类的原理和实例。这些工具类可以帮助我们在多个线程之间进行协调,实现更高效的并发编程。在使用这些工具类时,需要注意不同工具类的区别和使用场景,以及合理地控制线程的数量和访问权限,避免出现死锁等问题。

相关文章:

CountDownLatch、CyclicBarrier、Semaphore 的原理以及实例总结

文章目录 CountDownLatch、CyclicBarrier、Semaphore 的原理以及实例总结一、CountDownLatch二、CyclicBarrier三、Semaphore总结 CountDownLatch、CyclicBarrier、Semaphore 的原理以及实例总结 在Java多线程编程中&#xff0c;有三种常见的同步工具类&#xff1a;CountDownL…...

企业电子招投标系统源码之了解电子招标投标全流程

随着各级政府部门的大力推进&#xff0c;以及国内互联网的建设&#xff0c;电子招投标已经逐渐成为国内主流的招标投标方式&#xff0c;但是依然有很多人对电子招投标的流程不够了解&#xff0c;在具体操作上存在困难。虽然各个交易平台的招标投标在线操作会略有不同&#xff0…...

SpringCloud之Gateway组件简介

网关的理解 网关类似于海关或者大门&#xff0c;出入都需要经过这个网关。别人不经过这个网关&#xff0c;永远也看不到里面的东西。可以在网关进行条件过滤&#xff0c;比如大门只有对应的钥匙才能入内。网关和大门一样&#xff0c;永远暴露在最外面 不使用网关 前端需要记住每…...

GoNote第三章 主流框架加对比

GoNote第三章 主流框架加对比 Golang主流框架介绍 自从面市以来&#xff0c;Golang成为了程序员在编写API和开发Web服务时的首选之一。近90%的受访者表示会在自己下一组项目中持续使用Golang。与我们熟悉的C和C类似&#xff0c;Go语言也是现有Golang的“灵魂”。而Golang则是…...

Quartz框架详解分析

文章目录 1 Quartz框架1.1 入门demo1.2 Job 讲解1.2.1 Job简介1.2.2 Job 并发1.2.3 Job 异常1.2.4 Job 中断 1.3 Trigger 触发器1.3.1 SimpleTrigger1.3.2 CornTrigger 1.4 Listener监听器1.5 Jdbc store1.5.1 简介1.5.2 添加pom依赖1.5.3 建表SQL1.5.4 配置文件quartz.propert…...

Nginx专题-基于多网卡的主机配置

文章目录 Nginx 基于多网卡的主机实现一、虚拟机前置环境准备ifcfg-ens32配置文件的内容参考ifcfg-ens33配置文件的内容 二、案例演示修改nginx.conf配置文件解决中文乱码 Nginx 基于多网卡的主机实现 一、虚拟机前置环境准备 点击虚拟机右下角的 红色标框按钮&#xff0c;然后…...

4.2和4.3、MAC地址、IP地址、端口

计算机网络等相关知识可以去小林coding进行巩固&#xff08;点击前往&#xff09; 4.2和4.3、MAC地址、IP地址、端口 1.MAC地址的简介2.IP地址①IP地址简介②IP地址编址方式③A类IP地址④B类IP地址⑤C类IP地址⑥D类IP地址⑧子网掩码 3.端口①简介②端口类型 1.MAC地址的简介 …...

放弃 console.log 吧!用 Debugger 你能读懂各种源码

很多同学不知道为什么要用 debugger 来调试&#xff0c;console.log 不行么&#xff1f; 还有&#xff0c;会用 debugger 了&#xff0c;还是有很多代码看不懂&#xff0c;如何调试复杂源码呢&#xff1f; 这篇文章就来讲一下为什么要用这些调试工具&#xff1a; console.lo…...

epoll机制解析

一、epoll实现原理 1、实现原理 epoll通过3个方法来实现对句柄的监控操作&#xff0c;要深刻理解epoll&#xff0c;首先得了解epoll的三大关键要素&#xff1a;mmap、红黑树、链表。下面是epoll的框架图&#xff0c;如下&#xff1a; mmap epoll是通过内核与用户空间mmap同一块…...

基于 SpringBoot + Vue 实现的可视化拖拽编辑的大屏项目

今天给小伙伴们分享一个基于 SpringBoot Vue 实现的可视化拖拽编辑的大屏项目&#xff1b; 一、简介 这个是一个开源的一个BI平台&#xff0c;酷炫大屏展示&#xff0c;能随时随地掌控业务动态&#xff0c;让每个决策都有数据支撑。 多数据源支持&#xff0c;内置mysql、el…...

我们为什么要写作?

为什么要写书是一个很难回答的问题&#xff0c;因为从不同的角度&#xff0c;会有不同的答案。 最近ChatGPT很火&#xff01;诸事不决&#xff0c;先问问ChatGPT&#xff0c;看看它是怎么回答的。 ChatGPT给出的答案还是比较全&#xff0c;虽然没有“一本正经的胡说八道”&…...

设计模式:创建者模式 - 建造者模式

文章目录 1.概述2.结构3.实例4.优缺点5.使用场景6.模式扩展 1.概述 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 分离了部件的构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于&#xff1a;某…...

String a = new String(“abc“); 创建了几个对象?String a = “abc“; 呢?

String a new String(“abc”); 创建了几个对象&#xff1f;String a “abc”; 呢&#xff1f; 答案&#xff1a;String a new String(“abc”); 创建了1个或2个对象&#xff1b;String a “abc”; 创建了0个或1个都对象 String a new String(“abc”); 创建过程 首先在…...

keepalived+nginx安装

欢迎使用ShowDoc&#xff01; 1、安装基础包&#xff1a; yum -y install libnl libnl-devel 2、上传包&#xff1a; tar -zxvf keepalived-2.0.20.tar.gz -C /data/imas/base_soft mkdir -p /data/imas/base_soft/keepalived cd /data/imas/base_soft/keepalived-2.0.20 .…...

硬盘格式化工具,强烈推荐这个!

案例&#xff1a;硬盘格式化工具推荐 【我的电脑已经用了好几年了&#xff0c;硬盘存储容量严重不够了&#xff0c;最近想把它格式化&#xff0c;但却不知道怎么操作&#xff0c;大家有什么比较好的硬盘格式化工具可以推荐吗&#xff1f;】 硬盘作为存储设备&#xff0c;我们…...

Python的异常捕获和处理

程序在运行过程当中&#xff0c;不可避免的会出现一些错误&#xff0c;比如&#xff1a;使用了没有赋值过的变量&#xff0c;使用了不存在的索引&#xff0c;一个数字除以0 …… 这些错误在程序中&#xff0c;我们称其为异常。 程序运行过程中&#xff0c;一旦出现异常将会导致…...

oracle学习之rownum和rowid

rownum先百度一波https://www.cnblogs.com/xfeiyun/p/16355165.html rownum是oracle特有的一个关键字。 对于基表&#xff0c;在insert记录时&#xff0c;oracle就按照insert的顺序&#xff0c;将rownum分配给每一行记录&#xff0c;因此在select一个基表的时候&#xff0c;r…...

为什么说过早优化是万恶之源?

Donald Knuth&#xff08;高德纳&#xff09;是一位计算机科学界的著名学者和计算机程序设计的先驱之一。他被誉为计算机科学的“圣经”《计算机程序设计艺术》的作者&#xff0c;提出了著名的“大O符号”来描述算法的时间复杂度和空间复杂度&#xff0c;开发了TeX系统用于排版…...

如何用 ModelScope 实现 “AI 换脸” 视频

前言 当下&#xff0c;视频内容火爆&#xff0c;带有争议性或反差大的换脸视频总能吸引人视线。虽然 AI 换脸在市面上已经流行了许久&#xff0c;相关制作工具或移动应用也是数不胜数。但是多数制作工具多数情况下不是会员就是收费&#xff0c;而且替换模板有限。以下在实战的角…...

怎么样成为一名Python工程师?到底要会哪些东西?你会了多少?

目录 重点&#xff1a;爬虫部分项目、源码展示python数据分析可视化大屏看板python爬虫爬取淘宝卤鸭货商品数据python游戏开发python自动化办公 重点&#xff1a; 1、做一名程序员&#xff0c;绝对要耐得住寂寞&#xff0c;并且要一直有点兴趣促进你学习。如果你完全没兴趣&am…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...