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

并发工具CountDownLatch、CyclicBarrier、Semaphore

文章目录

  • 学习链接
  • CountDownLatch
    • CountDownLatch类的作用
    • 类的主要方法介绍
    • 图解await和countDown方法
    • 两个典型用法
    • 注意点
    • 总结
    • 示例
      • CountDownLatchDemo1
      • CountDownLatchDemo2
      • CountDownLatchDemo1And2
  • CyclicBarrier
    • CyclicBarrier循环栅栏
    • CyclicBarrier和CountDownLatch的区别
    • 示例
      • CyclicBarrierDemo
  • Semaphore
    • Semaphore信号量
    • Semaphore应用实例
    • 信号量的使用流程
    • 信号量主要方法介绍
    • 信号量的特殊用法
    • 注意点
    • 示例
      • SemaphoreDemo
  • Condition
    • Condition的作用
    • signalAll和signal的区别
    • Condition注意点
    • 示例
      • Condition1
      • Condition2

学习链接

Java并发编程第9讲——CountDownLatch、CyclicBarrier和Semaphore(万字详解)

CountDownLatch

CountDownLatch类的作用

在这里插入图片描述

类的主要方法介绍

在这里插入图片描述

图解await和countDown方法

在这里插入图片描述

两个典型用法

在这里插入图片描述

注意点

在这里插入图片描述

总结

在这里插入图片描述

示例

CountDownLatchDemo1

/*** 描述:工厂中,质检,5个工人检查,所有人都认为通过,才通过*/
public class CountDownLatchDemo1 {public static void main(String[] args) throws InterruptedException {CountDownLatch latch = new CountDownLatch(5);ExecutorService service = Executors.newFixedThreadPool(5);for (int i = 0; i < 5; i++) {final int no = i + 1;Runnable runnable = new Runnable() {@Overridepublic void run() {try {Thread.sleep((long) (Math.random() * 10000));System.out.println("No." + no + "完成了检查。");} catch (InterruptedException e) {e.printStackTrace();} finally {latch.countDown();}}};service.submit(runnable);}System.out.println("等待5个人检查完.....");latch.await();  // 这里也可以设置超时等待时间, 如: latch.await(5, TimeUnit.SECONDS);System.out.println("所有人都完成了工作,进入下一个环节。");}
}

CountDownLatchDemo2

/*** 描述:模拟100米跑步,5名选手都准备好了,只等裁判员一声令下,所有人同时开始跑步。*/
public class CountDownLatchDemo2 {public static void main(String[] args) throws InterruptedException {CountDownLatch begin = new CountDownLatch(1);ExecutorService service = Executors.newFixedThreadPool(5);for (int i = 0; i < 5; i++) {final int no = i + 1;Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("No." + no + "准备完毕,等待发令枪");try {begin.await();System.out.println("No." + no + "开始跑步了");} catch (InterruptedException e) {e.printStackTrace();}}};service.submit(runnable);}//裁判员检查发令枪...Thread.sleep(5000);System.out.println("发令枪响,比赛开始!");begin.countDown();}
}

CountDownLatchDemo1And2

/*** 描述:模拟100米跑步,5名选手都准备好了,只等裁判员一声令下,所有人同时开始跑步。当所有人都到终点后,比赛结束。*/
public class CountDownLatchDemo1And2 {public static void main(String[] args) throws InterruptedException {CountDownLatch begin = new CountDownLatch(1);CountDownLatch end = new CountDownLatch(5);ExecutorService service = Executors.newFixedThreadPool(5);for (int i = 0; i < 5; i++) {final int no = i + 1;Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("No." + no + "准备完毕,等待发令枪");try {begin.await();System.out.println("No." + no + "开始跑步了");Thread.sleep((long) (Math.random() * 10000));System.out.println("No." + no + "跑到终点了");} catch (InterruptedException e) {e.printStackTrace();} finally {end.countDown();}}};service.submit(runnable);}//裁判员检查发令枪...Thread.sleep(5000);System.out.println("发令枪响,比赛开始!");begin.countDown();end.await();System.out.println("所有人到达终点,比赛结束");}
}

CyclicBarrier

CyclicBarrier循环栅栏

在这里插入图片描述

CyclicBarrier和CountDownLatch的区别

在这里插入图片描述

示例

CyclicBarrierDemo

/*** 描述:    演示CyclicBarrier*/
public class CyclicBarrierDemo {public static void main(String[] args) {// 5个线程都调用await时,才执行Runnable,然后5个线程接着执行CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {@Overridepublic void run() {System.out.println("所有人都到场了, 大家统一出发!");}});// 这里循环10次,目的是验证CyclicBarrier可重用for (int i = 0; i < 10; i++) {new Thread(new Task(i, cyclicBarrier)).start();}}static class Task implements Runnable {private int id;private CyclicBarrier cyclicBarrier;public Task(int id, CyclicBarrier cyclicBarrier) {this.id = id;this.cyclicBarrier = cyclicBarrier;}@Overridepublic void run() {System.out.println("线程" + id + "现在前往集合地点");try {Thread.sleep((long) (Math.random() * 10000));System.out.println("线程" + id + "到了集合地点,开始等待其他人到达");cyclicBarrier.await();System.out.println("线程" + id + "出发了");} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}}
}

Semaphore

Semaphore信号量

在这里插入图片描述

Semaphore应用实例

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

信号量的使用流程

在这里插入图片描述

信号量主要方法介绍

在这里插入图片描述

信号量的特殊用法

在这里插入图片描述

注意点

在这里插入图片描述

示例

SemaphoreDemo

/*** 描述:     演示Semaphore用法*/
public class SemaphoreDemo {static Semaphore semaphore = new Semaphore(3, true);public static void main(String[] args) {ExecutorService service = Executors.newFixedThreadPool(50);for (int i = 0; i < 100; i++) {service.submit(new Task());}service.shutdown();}static class Task implements Runnable {@Overridepublic void run() {try {semaphore.acquire(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "拿到了许可证");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "释放了许可证");semaphore.release(1);}}
}

Condition

Condition的作用

在这里插入图片描述

signalAll和signal的区别

在这里插入图片描述

Condition注意点

在这里插入图片描述

示例

Condition1

/*** 描述:演示Condition的基本用法*/
public class ConditionDemo1 {private ReentrantLock lock = new ReentrantLock();private Condition condition = lock.newCondition();void method1() throws InterruptedException {lock.lock();try{System.out.println("条件不满足,开始await");condition.await(); // 可设置超时时间进入条件等待: condition.await(1, TimeUnit.SECONDS);System.out.println("条件满足了,开始执行后续的任务");}finally {lock.unlock();}}void method2() {lock.lock();try{System.out.println("准备工作完成,唤醒其他的线程");condition.signal();}finally {lock.unlock();}}public static void main(String[] args) throws InterruptedException {ConditionDemo1 conditionDemo1 = new ConditionDemo1();new Thread(new Runnable() {@Overridepublic void run() {try {Thread.sleep(1000);conditionDemo1.method2();} catch (InterruptedException e) {e.printStackTrace();}}}).start();conditionDemo1.method1();}
}

Condition2

/*** 描述:     演示用Condition实现生产者消费者模式*/
public class ConditionDemo2 {private int queueSize = 10;private PriorityQueue<Integer> queue = new PriorityQueue<Integer>(queueSize);private Lock lock = new ReentrantLock();// 当队列不满足 不满的条件时,生产者进入等待// (当队列不满时,唤醒在此条件中等待的线程)private Condition notFull = lock.newCondition();// 当队列不满足 不空的条件时,消费者进入等待// (当队列不空时,唤醒在此条件中等待的线程)private Condition notEmpty = lock.newCondition();public static void main(String[] args) {ConditionDemo2 conditionDemo2 = new ConditionDemo2();Producer producer = conditionDemo2.new Producer();Consumer consumer = conditionDemo2.new Consumer();producer.start();consumer.start();}class Consumer extends Thread {@Overridepublic void run() {consume();}private void consume() {while (true) {lock.lock();try {// 使用while, 防止了虚假唤醒while (queue.size() == 0) {System.out.println("队列空,等待数据");try {// 当队列为空时,进入等待// 当队列不为空时,被唤醒notEmpty.await(); // 进入条件队列中等待,并释放锁;此处被唤醒时,仍然需要获取到锁,才能往下运行} catch (InterruptedException e) {e.printStackTrace();}}// 走到这里说明队列肯定不为空了// (因为先持有了锁, 所以保证了操作的原子性。其它此时尝试从该队列中获取数据的线程将进入锁等待环节)queue.poll();// 因为拿到了锁, 并且从队列中获取了数据, 队列此时肯定不为满了, 所以可以唤醒生产者线程去生产notFull.signalAll();System.out.println("从队列里取走了一个数据,队列剩余" + queue.size() + "个元素");} finally {lock.unlock();}}}}class Producer extends Thread {@Overridepublic void run() {produce();}private void produce() {while (true) {lock.lock();try {// 使用while, 防止了虚假唤醒while (queue.size() == queueSize) {System.out.println("队列满,等待有空余");try {// 当队列为满时,进入等待// 当队列为不满时,被唤醒notFull.await();  // 进入条件队列中等待,并释放锁;此处被唤醒时,仍然需要获取到锁,才能往下运行} catch (InterruptedException e) {e.printStackTrace();}}// 走到这里说明队列肯定不为满了// (因为先持有了锁, 所以保证了操作的原子性。其它此时尝试往该队列中添加数据的线程将进入锁等待环节)queue.offer(1);// 因为拿到了锁, 并且往该队列中添加了数据, 队列此时肯定不为空了, 所以可以唤醒消费者者线程去消费notEmpty.signalAll();System.out.println("向队列插入了一个元素,队列剩余空间" + (queueSize - queue.size()));} finally {lock.unlock();}}}}}

相关文章:

并发工具CountDownLatch、CyclicBarrier、Semaphore

文章目录 学习链接CountDownLatchCountDownLatch类的作用类的主要方法介绍图解await和countDown方法两个典型用法注意点总结示例CountDownLatchDemo1CountDownLatchDemo2CountDownLatchDemo1And2 CyclicBarrierCyclicBarrier循环栅栏CyclicBarrier和CountDownLatch的区别示例Cy…...

十二. Redis 集群操作配置(超详细配图,配截图详细说明)

十二. Redis 集群操作配置(超详细配图&#xff0c;配截图详细说明) 文章目录 十二. Redis 集群操作配置(超详细配图&#xff0c;配截图详细说明)1. 为什么需要集群-高可用性2. 集群概述(及其搭建)3. Redis 集群的使用4. Redis 集群故障恢复5. Redis 集群的 Jedis 开发(使用Java…...

网络工程师 (26)TCP/IP体系结构

一、层次 四层&#xff1a; 网络接口层&#xff1a;TCP/IP协议的最底层&#xff0c;负责网络层与硬件设备间的联系。该层协议非常多&#xff0c;包括逻辑链路和媒体访问控制&#xff0c;负责与物理传输的连接媒介打交道&#xff0c;主要功能是接收数据报&#xff0c;并把接收到…...

TensorFlow域对抗训练DANN神经网络分析MNIST与Blobs数据集梯度反转层提升目标域适应能力可视化...

全文链接&#xff1a;https://tecdat.cn/?p39656 本文围绕基于TensorFlow实现的神经网络对抗训练域适应方法展开研究。详细介绍了梯度反转层的原理与实现&#xff0c;通过MNIST和Blobs等数据集进行实验&#xff0c;对比了不同训练方式&#xff08;仅源域训练、域对抗训练等&am…...

保姆级教程--DeepSeek部署

以DeepSeek-R1或其他类似模型为例&#xff0c;涵盖环境配置、代码部署和运行测试的全流程&#xff1a; 准备工作 1. 注册 Cloud Studio - 访问 [Cloud Studio 官网](https://cloudstudio.net/)&#xff0c;使用腾讯云账号登录。 - 完成实名认证&#xff08;如需长期使用…...

机器学习之心的创作纪念日

机缘 今天&#xff0c;是我成为创作者的第1460天。 在这段时间里&#xff0c;获得了很大的成长。 虽然日常忙碌但还在坚持创作、初心还在。 日常 创作已经成为我生活的一部分&#xff0c;尤其是在我的工作中&#xff0c;创作是不可或缺的&#xff0c;创作都是核心能力之一。…...

VeryReport和FastReport两款报表软件深度分析对比

在当今数据驱动的商业环境中&#xff0c;报表软件已经成为企业管理和数据分析的重要工具。无论是中小型企业还是大型企业&#xff0c;都需要依赖高效的报表工具来快速生成、分析和展示数据。市面上有许多报表工具&#xff0c;其中VeryReport和FastReport是两款备受关注的报表软…...

libtorch的c++,加载*.pth

一、转换模型为TorchScript 前提&#xff1a;python只保存了参数&#xff0c;没存结构 要在C中使用libtorch&#xff08;PyTorch的C接口&#xff09;&#xff0c;读取和加载通过torch.save保存的模型&#xff08; torch.save(pdn.state_dict()这种方式&#xff0c;只保存了…...

去除 RequestTemplate 对象中的指定请求头

目录 目标实现获取 RequestTemplate 对象去除请求头 目标 去除 RequestTemplate 对象中的指定请求头&#xff0c;如 Authorization 等。 实现 获取 RequestTemplate 对象 获取 RequestTemplate 对象的方式有很多种&#xff0c;如 通过 feign 虚拟客户端配置器&#xff1a; …...

b s架构 网络安全 网络安全架构分析

目录 文章目录 目录网络安全逻辑架构 微分段&#xff08;Micro-segmentation&#xff09;防火墙即服务&#xff08;Firewall asa Service &#xff0c;FWaaS&#xff09;安全网络网关&#xff08;Secure web gateway&#xff09;净化域名系统&#xff08;Sanitized Domain Na…...

【DeepSeek论文精读】2. DeepSeek LLM:以长期主义扩展开源语言模型

欢迎关注[【AIGC论文精读】](https://blog.csdn.net/youcans/category_12321605.html&#xff09;原创作品 【DeepSeek论文精读】1. 从 DeepSeek LLM 到 DeepSeek R1 【DeepSeek论文精读】2. DeepSeek LLM&#xff1a;以长期主义扩展开源语言模型 【DeepSeek论文精读】3. DeepS…...

Spring Boot和SpringMVC的关系

Spring Boot和SpringMVC都是Spring框架的一部分&#xff0c;但它们的作用和使用方式有所不同。为了更好地理解它们的关系&#xff0c;我们可以从以下几个方面进行详细说明&#xff1a; 1. SpringBoot的作用 SpringBoot是一个开源框架&#xff0c;它的目的是简化Spring应用程序…...

java基础4(黑马)

一、方法 1.定义 方法&#xff1a;是一种语法结构&#xff0c;它可以把一段代码封装成一个功能&#xff0c;以便重复使用。 方法的完整格式&#xff1a; package cn.chang.define;public class MethodDemo1 {public static void main(String[] args) {// 目标&#xff1a;掌…...

nodejs - vue 视频切片上传,本地正常,线上环境导致磁盘爆满bug

nodejs 视频切片上传&#xff0c;本地正常&#xff0c;线上环境导致磁盘爆满bug 原因&#xff1a; 然后在每隔一分钟执行du -sh ls &#xff0c;发现文件变得越来越大&#xff0c;即文件下的mp4文件越来越大 最后导致磁盘直接爆满 排查原因 1、尝试将m3u8文件夹下的所有视…...

注意力机制(Attention Mechanism)和Transformer模型的区别与联系

注意力机制(Attention Mechanism) 和 Transformer 模型 是深度学习领域中的两个重要概念,虽然它们紧密相关,但有着明显的区别。下面我们将从 定义、作用、结构 和 应用 等多个维度来分析这两者的区别与联系。 1. 定义 注意力机制(Attention Mechanism): 注意力机制是一…...

C++,设计模式,【单例模式】

文章目录 一、模式定义与核心价值二、模式结构解析三、关键实现技术演进1. 基础版(非线程安全)2. 线程安全版(双重检查锁)3. 现代C++实现(C++11起)四、实战案例:全局日志管理器五、模式优缺点深度分析✅ 核心优势⚠️ 潜在缺陷六、典型应用场景七、高级实现技巧1. 模板化…...

C++:类和对象初识

C&#xff1a;类和对象初识 前言类的引入与定义引入定义类的两种定义方法1. 声明和定义全部放在类体中2. 声明和定义分离式 类的成员变量命名规则 类的访问限定符及封装访问限定符封装 类的作用域与实例化类的作用域类实例化实例化方式&#xff1a; 类对象模型类对象的大小存储…...

官网下载Redis指南

1.访问官网 https://redis.io/downloads/#stack 2.点击redis图标 拉到下面点击download 在新页面拉到最下面&#xff0c;点击install from source 找到需要的大版本后&#xff0c;点击releases page 最后点击下载需要的版本号即可...

活动预告 |【Part1】 Azure 在线技术公开课:迁移和保护 Windows Server 和 SQL Server 工作负载

课程介绍 通过 Microsoft Learn 免费参加 Microsoft Azure 在线技术公开课&#xff0c;掌握创造新机遇所需的技能&#xff0c;加快对 Microsoft 云技术的了解。参加我们举办的“迁移和保护 Windows Server 和 SQL Server 工作负载”活动&#xff0c;了解 Azure 如何为将工作负…...

【Linux系统编程】五、进程创建 -- fork()

文章目录 前言Ⅰ. 重温fork函数一、fork()的概念二、如何理解fork()有两个返回值 Ⅱ.fork的常规用法Ⅲ. fork调用失败的原因Ⅳ. 写时拷贝为什么存在写时拷贝❓❓❓ 前言 现阶段我们知道进程创建有如下两种方式&#xff0c;其实包括在以后的学习中这两种方式也是最常见的&#…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...