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

Java 并发编程高级技巧:CyclicBarrier、CountDownLatch 和 Semaphore 的高级应用

Java 并发编程高级技巧:CyclicBarrier、CountDownLatch 和 Semaphore 的高级应用

一、引言

在 Java 并发编程中,CyclicBarrier、CountDownLatch 和 Semaphore 是三个常用且强大的并发工具类。它们在多线程场景下能够帮助我们实现复杂的线程协调与资源控制。本文将深入探讨这三个类的高级应用,旨在帮助读者更好地理解和运用这些并发工具来解决实际工作中遇到的多线程问题。

二、CyclicBarrier 的高级应用

(一)多阶段任务的协调

CyclicBarrier 可以用于多阶段任务的场景,例如在一个复杂的计算任务中,需要将任务分为多个阶段,多个线程分别处理不同阶段的数据,只有当所有线程都完成当前阶段的任务后,才能进入下一个阶段。

import java.util.concurrent.CyclicBarrier;public class CyclicBarrierExample {public static void main(String[] args) {int numThreads = 3; // 线程数CyclicBarrier barrier = new CyclicBarrier(numThreads, () -> {System.out.println("所有线程都完成当前阶段,进入下一阶段");});for (int i = 0; i < numThreads; i++) {new Thread(() -> {for (int stage = 1; stage <= 3; stage++) { // 3 个阶段的任务System.out.println(Thread.currentThread().getName() + " 开始处理阶段 " + stage);try {Thread.sleep((long) (Math.random() * 1000)); // 模拟任务处理时间System.out.println(Thread.currentThread().getName() + " 完成处理阶段 " + stage);barrier.await(); // 等待所有线程完成当前阶段} catch (Exception e) {e.printStackTrace();}}}).start();}}
}

在这个例子中,我们创建了 3 个线程来处理 3 个阶段的任务。每个阶段的末尾,线程都会调用 barrier.await() 方法等待其他线程完成当前阶段的任务。当所有线程都到达屏障点后,屏障的阻塞状态被重置,所有线程可以继续进入下一个阶段。通过这种方式,我们实现了多阶段任务的协调处理。

(二)性能优化与源码解析

CyclicBarrier 内部是通过循环Barrier机制来实现的。其核心是通过一个计数器来记录到达屏障点的线程数。当计数器达到指定的线程数时,释放所有等待的线程,并重置计数器。这种机制使得 CyclicBarrier 可以循环使用,即在多个任务阶段中重复使用同一个屏障。

在性能优化方面,我们需要注意 CyclicBarrier 的屏障数(构造函数中的参数)的选择。过大的屏障数可能导致线程等待时间过长,影响程序的响应速度;而过小的屏障数可能无法满足任务协调的需求。在实际应用中,需要根据任务的特性和线程的工作负载来合理设置屏障数。

三、CountDownLatch 的高级应用

(一)资源初始化与任务启动控制

CountDownLatch 可以用于控制资源的初始化和任务的启动。例如,在多线程应用程序中,我们需要确保某些资源(如配置文件、数据库连接池等)在所有工作线程开始执行任务之前已经初始化完成。我们可以通过设置一个初始计数的 CountDownLatch,多个线程在开始任务前都先调用 await() 方法等待计数器变为 0,而负责初始化资源的线程在完成初始化后调用 countDown() 方法减少计数器的值。

import java.util.concurrent.CountDownLatch;public class CountDownLatchExample {public static void main(String[] args) {final int numThreads = 5;CountDownLatch latch = new CountDownLatch(1); // 初始计数为 1// 工作线程for (int i = 0; i < numThreads; i++) {new Thread(() -> {try {System.out.println(Thread.currentThread().getName() + " 等待资源初始化完成");latch.await(); // 等待资源初始化完成System.out.println(Thread.currentThread().getName() + " 资源初始化完成,开始执行任务");} catch (InterruptedException e) {e.printStackTrace();}}).start();}// 模拟资源初始化过程new Thread(() -> {System.out.println("开始初始化资源");try {Thread.sleep(2000); // 模拟资源初始化所需时间System.out.println("资源初始化完成");latch.countDown(); // 初始化完成,减少计数器} catch (InterruptedException e) {e.printStackTrace();}}).start();}
}

在这个例子中,5 个工作线程都先等待 CountDownLatch 的计数器变为 0。负责初始化资源的线程在完成初始化后调用 countDown() 方法,使得工作线程可以从 await() 方法中唤醒,开始执行任务。这种机制确保了资源的正确初始化和任务的有序启动。

(二)性能测试与源码机制

CountDownLatch 的实现是通过一个内部的同步器(AQS)来管理计数器的。当计数器为 0 时,同步器会释放所有等待的线程。CountDownLatch 的计数器只能减少,不能增加,这使得它适用于一次性事件等待的场景。

在性能测试方面,CountDownLatch 可以用于控制多个线程同时开始执行任务,从而测量任务的执行时间和性能。例如,在测试某个计算密集型任务的性能时,我们可以使用多个线程同时执行任务,并通过 CountDownLatch 来控制这些线程同时开始执行,然后记录任务的完成时间。

四、Semaphore 的高级应用

(一)资源访问控制与流量控制

Semaphore 可以用于控制对资源的访问和流量控制。例如,在一个高并发的 Web 应用中,为了防止服务器过载,我们可以使用 Semaphore 来限制同时处理的请求数量。当请求数量超过设定的许可数时,后续的请求将被阻塞,直到有许可可用。

import java.util.concurrent.Semaphore;public class SemaphoreExample {public static void main(String[] args) {final int numThreads = 10;final int permits = 3; // 设置许可数为 3final Semaphore semaphore = new Semaphore(permits);// 多个请求线程for (int i = 0; i < numThreads; i++) {new Thread(() -> {try {System.out.println(Thread.currentThread().getName() + " 正在等待获取许可");semaphore.acquire(); // 获取许可System.out.println(Thread.currentThread().getName() + " 获取许可,开始处理请求");Thread.sleep((long) (Math.random() * 2000)); // 模拟处理请求时间System.out.println(Thread.currentThread().getName() + " 处理请求完成,释放许可");semaphore.release(); // 释放许可} catch (InterruptedException e) {e.printStackTrace();}}).start();}}
}

在这个例子中,我们设置了 3 个许可。当有多个请求线程同时尝试获取许可时,只有 3 个线程可以同时获得许可并处理请求。其他线程将被阻塞,等待许可释放。这种机制可以有效地控制资源的访问和流量,防止系统过载。

(二)公平性与性能优化

Semaphore 有公平和非公平两种模式。公平模式下,线程按照请求的顺序获取许可;非公平模式下,线程可能随机获取许可。非公平模式通常具有更高的吞吐量,因为它允许更多的线程尝试获取许可。在实际应用中,我们需要根据具体的场景和需求来选择公平或非公平模式。

在性能优化方面,我们需要注意 Semaphore 的许可数设置。过小的许可数可能导致系统资源未充分利用,请求处理速度过慢;过大的许可数可能导致系统过载。我们需要根据系统的实际负载能力和服务请求的特点来合理设置许可数,以达到最佳的性能平衡。

五、总结

CyclicBarrier、CountDownLatch 和 Semaphore 是 Java 并发编程中不可或缺的工具类。通过本文的介绍,我们深入探讨了它们的高级应用,包括多阶段任务协调、资源初始化与任务启动控制、资源访问控制与流量控制等场景。同时,我们也对它们的源码机制和性能优化策略进行了分析。在实际开发中,灵活运用这些并发工具类,可以大大提高我们处理复杂多线程问题的能力,构建高效、可靠的并发应用程序。

在这里插入图片描述

相关文章:

Java 并发编程高级技巧:CyclicBarrier、CountDownLatch 和 Semaphore 的高级应用

Java 并发编程高级技巧&#xff1a;CyclicBarrier、CountDownLatch 和 Semaphore 的高级应用 一、引言 在 Java 并发编程中&#xff0c;CyclicBarrier、CountDownLatch 和 Semaphore 是三个常用且强大的并发工具类。它们在多线程场景下能够帮助我们实现复杂的线程协调与资源控…...

PT5F2307触摸A/D型8-Bit MCU

1. 产品概述 ● PT5F2307是一款51内核的触控A/D型8位MCU&#xff0c;内置16K*8bit FLASH、内部256*8bit SRAM、外部512*8bit SRAM、触控检测、12位高精度ADC、RTC、PWM等功能&#xff0c;抗干扰能力强&#xff0c;适用于滑条遥控器、智能门锁、消费类电子产品等电子应用领域。 …...

矩阵方程$Ax=b$的初步理解.

对于矩阵方程 A x b A\textbf{\textit{x}}\textbf{\textit{b}} Axb&#xff0c;可能就是一学而过&#xff0c;也可能也就会做做题&#xff0c;但是从如何直观地理解它呢?   这个等式可以用多种理解方式&#xff0c;这里就从向量变换角度浅谈一下。其中的 A A A是矩阵&#…...

线性代数中的向量与矩阵:AI大模型的数学基石

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…...

[特殊字符] 使用增量同步+MQ机制将用户数据同步到Elasticsearch

在开发用户搜索功能时&#xff0c;我们通常会将用户信息存储到 Elasticsearch&#xff08;简称 ES&#xff09; 中&#xff0c;以提高搜索效率。本篇文章将详细介绍我们是如何实现 MySQL 到 Elasticsearch 的增量同步&#xff0c;以及如何通过 MQ 消息队列实现用户信息实时更新…...

LeetCode 2942.查找包含给定字符的单词:使用库函数完成

【LetMeFly】2942.查找包含给定字符的单词&#xff1a;使用库函数完成 力扣题目链接&#xff1a;https://leetcode.cn/problems/find-words-containing-character/ 给你一个下标从 0 开始的字符串数组 words 和一个字符 x 。 请你返回一个 下标数组 &#xff0c;表示下标在数…...

【mediasoup】MS_DEBUG_DEV 等日志形式转PLOG输出

输出有问题 MS_DEBUG_DEV("[pacer_updated pacing_kbps:%" PRIu32 ",padding_budget_kbps:%" PRIu32 "]",pacing_bitrate_kbps_,/*cc给出的目标码率 * 系数*/padding_rate_bps / 1000 /*设置值*/);...

打卡第27天:函数的定义与参数

知识点回顾&#xff1a; 1.函数的定义 2.变量作用域&#xff1a;局部变量和全局变量 3.函数的参数类型&#xff1a;位置参数、默认参数、不定参数 4.传递参数的手段&#xff1a;关键词参数 5.传递参数的顺序&#xff1a;同时出现三种参数类型时 作业&#xff1a; 题目1&a…...

python训练营day34

知识点回归&#xff1a; CPU性能的查看&#xff1a;看架构代际、核心数、线程数GPU性能的查看&#xff1a;看显存、看级别、看架构代际GPU训练的方法&#xff1a;数据和模型移动到GPU device上类的call方法&#xff1a;为什么定义前向传播时可以直接写作self.fc1(x) 作业 复习今…...

人工智能在医疗影像诊断上的最新成果:更精准地识别疾病

摘要&#xff1a;本论文深入探讨人工智能在医疗影像诊断领域的最新突破&#xff0c;聚焦于其在精准识别疾病方面的显著成果。通过分析深度学习、多模态影像融合、三维重建与可视化以及智能辅助诊断系统等关键技术的应用&#xff0c;阐述人工智能如何提高医疗影像诊断的准确性和…...

塔能节能平板灯:点亮苏州某零售工厂节能之路

在苏州某零售工厂的运营成本中&#xff0c;照明能耗占据着一定比例。为降低成本、提升能源利用效率&#xff0c;该工厂与塔能科技携手&#xff0c;引入塔能节能平板灯&#xff0c;开启了精准节能之旅&#xff0c;并取得了令人瞩目的成效。 一、工厂照明能耗困境 苏州该零售工厂…...

3DMAX插件UV工具UV Tools命令参数详解

常规: 打开UV工具设置对话框。 右键点击: 隐藏/显示主界面。 添加 为选定对象添加展开修改器。 将从下拉菜单中选择映射通道。 Ctrl+点击: 克隆任何当前的修饰符。 右键点击: 找到第一个未展开的修改器。 地图频道 设置展开映射通道。 Ctrl+Click:添加选定的映射通道的展开…...

Docker 与微服务架构:从单体应用到容器化微服务的迁移实践

随着软件系统规模和复杂性的日益增长,传统的单体应用(Monolithic Application)在开发效率、部署灵活性和可伸缩性方面逐渐暴露出局限性。微服务架构(Microservice Architecture)作为一种将大型应用拆分为一系列小型、独立、松耦合服务的模式,正成为现代企业构建弹性、敏捷…...

《岁月深处的童真》

在那片广袤而质朴的黄土地上&#xff0c;时光仿佛放慢了脚步&#xff0c;悠悠地流淌着。画面的中央&#xff0c;是一个扎着双髻的小女孩&#xff0c;她静静地伫立着&#xff0c;宛如一朵绽放在岁月缝隙中的小花。 小女孩身着一件略显陈旧的中式上衣&#xff0c;布料的纹理间似乎…...

文件夹图像批处理教程

前言 因为经常对图像要做数据清洗&#xff0c;又很费时间去重新写一个&#xff0c;我一直在想能不能写一个通用的脚本或者制作一个可视化的界面对文件夹图像做批量的修改图像大小、重命名、划分数据训练和验证集等等。这里我先介绍一下我因为写过的一些脚本&#xff0c;然后我…...

RL电路的响应

学完RC电路的响应&#xff0c;又过了一段时间了&#xff0c;想必很多人都忘了RC电路响应的一些内容。我们这次学习RL电路的响应&#xff0c;以此同时&#xff0c;其实也是带大家一起回忆一些之前所学的RC电路的响应的一些知识点。所以&#xff0c;这次的学习&#xff0c;其实也…...

30-消息队列

一、消息队列概述 队列又称消息队列&#xff0c;是一种常用于任务间通信的数据结构&#xff0c;队列可以在任务与任务间、 中断和任务间传递信息&#xff0c;实现了任务接收来自其他任务或中断的不固定长度的消息&#xff0c;任务能够从队列里面读取消息&#xff0c;当队列中的…...

跨域解决方案之JSONP

目录 一、JSONP 核心原理 二、JSONP 实现步骤 &#xff08;一&#xff09;客户端代码 &#xff08;二&#xff09;服务器端代码&#xff08;ASP.NET实现&#xff09; 1. ASP.NET Web Forms 实现 2. ASP.NET Core 实现 三、JSONP 优缺点 &#xff08;一&#xff09;优点 …...

【AI测试革命】第七期:AI性能测试的深度实践——从智能建模到自动化调优的全链路升级

在微服务架构与高并发场景普及的当下&#xff0c;性能测试作为保障系统稳定性和用户体验的核心环节&#xff0c;正面临负载模型构建复杂、脚本维护成本高、瓶颈定位效率低等挑战。Copilot凭借代码生成、数据分析和智能决策能力&#xff0c;为性能测试全流程注入新动能&#xff…...

Thinkphp6使用token+Validate验证防止表单重复提交

htm页面加 <input type"hidden" name"__token__" value"{:token()}" /> Validate 官方文档 ThinkPHP官方手册...

AppAgentx 开源AI手机操控使用分享

项目地址: https://appagentx.github.io/?utm_sourceai-bot.cn GitHub仓库: https://github.com/Westlake-AGI-Lab/AppAgentX/tree/main arXiv技术论文:https://arxiv.org/pdf/2503.02268 AppAgentx是什么: AppAgentX 是西湖大学推出的一种自我进化式 GUI 代理框架。它通过…...

Axure设计之带分页的穿梭框原型

穿梭框&#xff08;Transfer&#xff09;是一种常见且实用的交互组件&#xff0c;广泛应用于需要批量选择或分配数据的场景。 一、应用场景 其典型应用场景包括&#xff1a; 权限管理系统&#xff1a;批量分配用户角色或系统权限数据筛选工具&#xff1a;在大数据集中选择特…...

嵌入式硬件篇---陀螺仪|PID

文章目录 前言1. 硬件准备主控芯片陀螺仪模块电机驱动电源其他2. 硬件连接3. 软件实现步骤(1) MPU6050初始化与数据读取(2) 姿态解算(互补滤波或DMP)(3) PID控制器设计(4) 麦克纳姆轮协同控制4. 主程序逻辑5. 关键优化与调试技巧(1) 传感器校准(2) PID参数整定先调P再调D最后…...

电机控制储备知识学习(五) 三项直流无刷电机(BLDC)学习(四)

目录 电机控制储备知识学习&#xff08;五&#xff09;一、三项直流无刷电机(BLDC)学习&#xff08;四&#xff09;1&#xff09;软件方法控制电机转速2&#xff09;PWM概念和PWM的产生3&#xff09;转子位置检测和霍尔传感器的工作原理分析4&#xff09;霍尔传感器安装角度和电…...

Java—— 网络爬虫

案例要求 https://hanyu.baidu.com/shici/detail?pid0b2f26d4c0ddb3ee693fdb1137ee1b0d&fromkg0 http://www.haoming8.cn/baobao/10881.html http://www.haoming8.cn/baobao/7641.html上面三个网址分别表示百家姓&#xff0c;男生名字&#xff0c;女生名字&#xff0c;如…...

Baklib内容中台的主要构成是什么?

Baklib内容中台核心架构 Baklib作为一站式知识管理平台的核心载体&#xff0c;其架构设计围绕智能搜索引擎优化技术与多终端适配响应系统展开。通过模块化内容组件的灵活配置&#xff0c;企业可快速搭建知识库、FAQ页面及帮助中心等标准化场景&#xff0c;同时借助可视化数据看…...

深度解析 Java 中介者模式:重构复杂交互场景的优雅方案

一、中介者模式的核心思想与设计哲学 在软件开发的历史长河中&#xff0c;对象间的交互管理一直是架构设计的核心难题。当多个对象形成复杂的网状交互时&#xff0c;系统会陷入 "牵一发而动全身" 的困境。中介者模式&#xff08;Mediator Pattern&#xff09;作为行…...

家用和类似用途电器的安全 第1部分:通用要求 与2005版差异(7)

文未有本标准免费下载链接。 ——增加了“对峰值电压大于15kV的&#xff0c;其放电电能应不超过350mJ”的要求&#xff08;见8.1.4&#xff09; 1. GB/T4706.1-2024&#xff1a; 8.1.4 如果易触及部件为下述情况,则不认为其是带电的。 ——该部件由安全特低电压供电,且: 对…...

HTTP Digest 认证:原理剖析与服务端实现详解

HTTP Digest 认证&#xff1a;原理剖析与服务端实现详解 HTTP 协议中的 Digest 认证&#xff08;摘要认证&#xff09;是一种比 Basic 认证更安全的身份验证机制&#xff0c;其核心设计是避免密码明文传输&#xff0c;并通过动态随机数&#xff08;Nonce&#xff09;防范重放攻…...

untiy实现汽车漫游

实现效果 汽车漫游 1.创建汽车模型 导入汽车模型(FBX格式或其他3D格式),确保模型包含车轮、车身等部件。 为汽车添加碰撞体(如 Box Collider 或 Mesh Collider),避免穿透场景物体。 添加 Rigidbody 组件,启用重力并调整质量(Mass)以模拟物理效果。 2.编写汽车控制脚本…...