CyclicBarrier、Semaphore、CountDownLatch的区别,适用场景

news2025/4/13 7:12:05

CyclicBarrierSemaphoreCountDownLatch 是 Java 并发包中用于线程协作的工具类,它们虽然都与线程同步相关,但设计目的和使用场景有显著差异。以下是它们的核心区别和典型应用场景:

1. CountDownLatch

核心机制
  • 一次性计数器:初始化时指定一个固定数值(count),线程调用 countDown() 减少计数器,其他线程通过 await() 等待计数器归零。
  • 不可重置:计数器归零后无法重复使用。
适用场景
  • 主线程等待子线程完成初始化:例如主线程等待所有服务启动后再处理请求。
  • 并行任务完成后汇总结果:多个子任务并行执行,主线程等待所有子任务完成后再汇总。
  • 模拟并发测试:通过 CountDownLatch 让所有线程同时开始执行。
特点
  • 一次性使用:计数器归零后不可重置。
  • 无回调机制,仅用于同步等待。
示例
CountDownLatch latch = new CountDownLatch(3);

// 子线程完成任务后调用 countDown()
executor.submit(() -> {
    doTask();
    latch.countDown();
});

// 主线程等待所有子线程完成
latch.await();

2. CyclicBarrier

核心机制
  • 可重复使用的屏障:一组线程相互等待,直到所有线程到达屏障点后,再一起继续执行。
  • 支持回调:可以指定一个 Runnable 任务,在所有线程到达屏障后触发。
适用场景
  • 多阶段任务协作:例如并行计算需要分阶段处理,每个阶段需等待所有线程完成。
  • 数据分批处理:多个线程处理数据后,在屏障点合并结果。
  • 模拟复杂并发逻辑:如多玩家游戏的回合制同步。
特点
  • 可重用:通过 reset() 方法重置计数器。
  • 支持屏障后回调函数,用于统一处理阶段结果。
示例
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
    System.out.println("所有线程到达屏障点");
});

executor.submit(() -> {
    doPhase1();
    barrier.await(); // 等待其他线程
    doPhase2();
});

3. Semaphore

核心机制
  • 资源访问控制:通过“许可证”机制限制同时访问共享资源的线程数。
  • 支持公平/非公平模式:防止线程饥饿。
适用场景
  • 资源池管理:如数据库连接池、线程池。
  • 限流:控制接口的最大并发请求数。
  • 互斥锁扩展:通过 Semaphore(1) 实现类似锁的功能(但更灵活,可跨方法释放)。
特点
  • 动态调整:通过 acquire()release() 增减许可数。
  • 支持超时和中断响应,避免死锁。
示例
Semaphore semaphore = new Semaphore(5); // 允许5个线程同时访问

void accessResource() {
    semaphore.acquire(); // 获取许可
    try {
        useResource();
    } finally {
        semaphore.release(); // 释放许可
    }
}

关键区别总结

特性CountDownLatchCyclicBarrierSemaphore
重置能力一次性,不可重置可重复使用可重复使用
核心目的主线程等待子线程完成特定操作线程相互等待到屏障点控制资源访问的并发数
计数器方向递减(countDown()递增(await()获取/释放许可证(acquire()/release()
协作关系主线程等待子线程线程间相互等待线程与资源之间的协调
是否支持回调是(到达屏障后触发任务)
典型场景主从线程同步分阶段并行任务协同限流、资源池管理

如何选择?

  • 线程组协同(多阶段)CyclicBarrier
  • 主线程等待子线程完成CountDownLatch
  • 控制并发访问量或资源池Semaphore
  • 需重用或动态调整计数器CyclicBarrier 或 Semaphore

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

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

相关文章

【c++深入系列】:类与对象详解(中)

🔥 本文专栏:c 🌸作者主页:努力努力再努力wz 💪 今日博客励志语录: 不是因为看到希望才坚持,而是坚持了才能看到希望 那么上一篇博客我讲解了什么是类和对象以及类和对象是怎么定义的&#xff0…

汽车 HMI 设计的发展趋势与设计要点

一、汽车HMI设计的发展历程与现状 汽车人机交互界面(HMI)设计经历了从简单到复杂、从单一到多元的演变过程。2012年以前,汽车HMI主要依赖物理按键进行操作,交互方式较为单一。随着特斯拉Model S的推出,触控屏逐渐成为…

《AI大模型应知应会100篇》第56篇:LangChain快速入门与应用示例

第56篇:LangChain快速入门与应用示例 前言 最近最火的肯定非Manus和OpenManus莫属,因为与传统AI工具仅提供信息不同,Manus能完成端到端的任务闭环。例如用户发送“筛选本月抖音爆款视频”,它会自动完成: 爬取平台数据…

Java 大视界 -- Java 大数据在智能农业无人机植保作业路径规划与药效评估中的应用(165)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…

哈希表系列一>两数之和

目录 题目:方法:暴力代码:优化后代码: 题目: 链接: link 方法: 暴力代码: public int[] twoSum(int[] nums, int target) {解法一:暴力解法:int n nums.length;for(int…

CAD插件实现:自动递增编号(前缀、后缀、位数等)——CADc#实现

cad中大量输入一定格式的递增编号时,可用插件实现,效果如下: ①本插件可指定数字位数、起始号码、加前缀、后缀、文字颜色等(字体样式和文字所在图层为cad当前图层和当前字体样式)。 ②插件采用Jig方式,即…

C语言--回文字符串

输入:字符串,判断是否是回文字符串,例如abcba输出Yes 输出:是否 代码 思路:使用两个指针分别指向头和尾,依次对比第一个元素和最后一个元素,第二个和倒数第二个元素,如果遇到不相同…

Coco-AI 支持嵌入,让你的网站拥有 AI 搜索力

在之前的实践中,我们已经成功地把 Hexo、Hugo 等静态博客和 Coco-AI 检索系统打通了:只要完成向量化索引,就可以通过客户端问答界面实现基于内容的智能检索。 这一层已经很好用了,但总觉得少了点什么—— 比如用户还得专门打开一…

TRDI 公司的RiverPro 和 RioPro ADCP 用户指南

TRDI 公司 RiverPro 和 RioPro ADCP 用户指南 简介第一章 - 概述第二章 - 安装第三章 - 采集数据第四章 - 维护第五章 - 测试RIVERPRO/RIOPRO第六章 - 故障排除第七章 - 将系统返回TRDI进行维修第八章 - 规格第九章 - 命令第十章 - 输出数据格式附录A-合规通知首次完整翻译《Ri…

OpenCV 图形API(11)对图像进行掩码操作的函数mask()

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 描述 对矩阵应用掩码。 该函数mask设置来自给定矩阵的值,如果掩码矩阵中对应的像素值设为true,否则将矩阵的值设为0。 支持的源矩阵…

使用C#写的一个Kafka的使用工具

由于offset不支持通过界面推送数据,所以我写了一个kafka的连接工具,能够直接从界面推送数据,方便使用。由于使用的是C#写的,所以比offset要流畅的多。 1、数据源连接 2、获取集群的topic 3、点击获取数据能够获取最新的100条数…

【通知】STM32MP157驱动开发课程全新升级!零基础入门嵌入式Linux驱动,掌握底层开发核心技能!

在嵌入式Linux系统开发中,驱动程序开发是一项关键技术,它作为硬件与软件之间的桥梁,实现了操作系统对硬件设备的控制。相较于嵌入式Linux应用开发,驱动开发由于涉及底层硬件且抽象程度较高,往往让初学者感到难度较大。…

飞浆PaddlePaddle 猫狗数据大战

猫狗数据大战 1 数据集的准备以及处理操作1.1 数据集1.2 文件解压操作(python) 1.3 数据的分类1.4 创建训练集和测试集 2 网络构建CNN版本--DeepID 人脸识别网络结构DeepID 与 CNN 网络结构的差异 3 深度学习模型训练和推理的核心设置4 制图5 训练6 预测…

使用高德api实现天气查询

创建应用获取 Key 天气查询-基础 API 文档-开发指南-Web服务 API | 高德地图API 代码编写 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-wid…

Could not find artifact com.microsoft.sqlserver:sqljdbc4:jar:4.0 in central

具体错误 [ERROR] Failed to execute goal on project datalink-resource: Could not resolve dependencies for project com.leon.datalink:datalink-resource:jar:1.0.0: Could not find artifact com.microsoft.sqlserver:sqljdbc4:jar:4.0 in central (https://repo.maven…

Express学习笔记(三)——使用 Express 写接口

目录 1. 创建基本的服务器 2. 创建 API 路由模块 3. 编写 GET 接口 4. 编写 POST 接口 5. CORS 跨域资源共享 5.1 接口的跨域问题 5.2 使用 cors 中间件解决跨域问题 5.3 什么是 CORS 5.4 CORS 的注意事项 5.5 CORS 响应头部 - Access-Control-Allow-Origin 5.6 COR…

【HarmonyOS Next之旅】DevEco Studio使用指南(十)

目录 1 -> Optimize Imports功能 2 -> 父/子类快速跳转 3 -> 查看接口/类的层次结构 4 -> 代码自动补全 1 -> Optimize Imports功能 使用编辑器提供的Optimize Imports&#xff0c;可以快速清除未使用的import&#xff0c;并根据设置的规则对import进行合并…

java并发编程-并发容器

并发容器 CopyOnWriteArrayListCopyOnWriteArraySetConcurrentHashMapConcurrentSkipListMap迭代器的fail-fast与fail-safe机制应用场景 CopyOnWriteArrayList 线程不安全容器&#xff1a;ArrayList代替Vector、synchronizedList适用于读多写少的场景&#xff0c;对读操作不加…

PPT助手:一款集计时、远程控制与多屏切换于一身的PPT辅助工具

PPT助手&#xff1a;一款集计时、远程控制与多屏切换于一身的PPT辅助工具 &#x1f4dd;&#x1f3a4; 在现代化的演讲和演示中&#xff0c;如何高效地控制PPT进程、保证展示的流畅性与精准性&#xff0c;成为了每个演讲者必须面对的挑战。无论是商务汇报、学术演讲&#xff0…

大模型应用初学指南

随着人工智能技术的快速发展&#xff0c;检索增强生成&#xff08;RAG&#xff09;作为一种结合检索与生成的创新技术&#xff0c;正在重新定义信息检索的方式&#xff0c;RAG 的核心原理及其在实际应用中的挑战与解决方案&#xff0c;通用大模型在知识局限性、幻觉问题和数据安…