并发设计模式实战系列(16):屏障(Barrier)
🌟 大家好,我是摘星! 🌟
今天为大家带来的是并发设计模式实战系列,第十六章屏障(Barrier),废话不多说直接开始~
目录
一、核心原理深度拆解
1. 屏障的同步机制
2. 关键参数
二、生活化类比:团队登山
三、Java代码实现(生产级Demo)
1. 完整可运行代码
2. 关键方法说明
四、横向对比表格
1. 同步工具对比
2. 屏障参数配置对比
五、高级应用技巧
1. 多阶段任务控制
2. 动态线程管理
3. 性能监控
六、工程实践中的陷阱与解决方案
1. 死锁风险场景
2. 屏障断裂处理
七、性能优化技巧
1. 分层屏障设计
2. 与ForkJoinPool结合
八、分布式屏障扩展(ZooKeeper实现)
1. 核心原理
2. Java代码片段
九、监控与调试方案
1. 关键监控指标
2. Arthas诊断命令
十、与其他模式的组合应用
1. 屏障 + 生产者消费者模式
2. 代码示例
一、核心原理深度拆解
1. 屏障的同步机制
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 线程1 │ │ 线程2 │ │ 线程N │
│ 执行阶段1 │ │ 执行阶段1 │ │ 执行阶段1 │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘│ │ │└─────────┬────────┴────────┬─────────┘│ 屏障点 │▼ ▼┌───────────────────┐│ 所有线程到达后 ││ 才继续执行阶段2 │└───────────────────┘
- 协调机制:强制多个线程在某个点等待,直到所有参与线程都到达该点
- 重置特性:CyclicBarrier 可重复使用(自动重置),CountDownLatch 不可重置
2. 关键参数
- parties:需要等待的线程数量
- barrierAction:所有线程到达后触发的回调(可选)
二、生活化类比:团队登山
系统组件 | 现实类比 | 核心行为 |
线程 | 登山队员 | 各自以不同速度攀登 |
屏障点 | 集合点 | 必须所有队员到齐才能继续前进 |
barrierAction | 领队 | 检查装备、宣布下一阶段路线 |
- 异常处理:若有队员受伤(线程中断),其他队员需要决定是否继续等待
三、Java代码实现(生产级Demo)
1. 完整可运行代码
import java.util.concurrent.*;
import java.util.Random;public class BarrierPatternDemo {// 登山模拟static class MountainClimbing {private final CyclicBarrier barrier;private final Random rand = new Random();public MountainClimbing(int teamSize) {// 屏障点设置:队伍到齐后执行领队指令this.barrier = new CyclicBarrier(teamSize, () -> {System.out.println("\n=== 所有队员已到达集合点 ===");System.out.println("领队:检查装备完毕,向下一营地前进!");});}public void climb(String name) {try {// 第一阶段攀登int time = rand.nextInt(3000);System.out.printf("%s 正在攀登第一段(预计%dms)...\n", name, time);Thread.sleep(time);System.out.printf("[%s] 到达第一集合点,等待队友...\n", name);barrier.await(); // 等待所有队员// 第二阶段(屏障解除后)time = rand.nextInt(4000);System.out.printf("%s 向顶峰冲刺(预计%dms)...\n", name, time);Thread.sleep(time);System.out.printf("[%s] 成功登顶!\n", name);} catch (InterruptedException | BrokenBarrierException e) {System.out.printf("[%s] 登山中断: %s\n", name, e.getMessage());}}}public static void main(String[] args) {final int TEAM_SIZE = 3;MountainClimbing expedition = new MountainClimbing(TEAM_SIZE);// 创建登山线程ExecutorService pool = Executors.newFixedThreadPool(TEAM_SIZE);for (int i = 1; i <= TEAM_SIZE; i++) {String name = "队员-" + i;pool.execute(() -> expedition.climb(name));}pool.shutdown();}
}
2. 关键方法说明
// 1. 屏障等待(可设置超时)
barrier.await(5, TimeUnit.SECONDS);// 2. 检查屏障状态
barrier.isBroken(); // 是否有线程被中断
barrier.getNumberWaiting(); // 当前等待的线程数// 3. 重置屏障(CyclicBarrier特有)
barrier.reset();
四、横向对比表格
1. 同步工具对比
工具 | 可重用性 | 可中断 | 额外功能 | 适用场景 |
CyclicBarrier | ✓ | ✓ | 支持回调(barrierAction) | 多阶段任务同步 |
CountDownLatch | ✗ | ✓ | 一次性 | 主线程等待多个子线程完成 |
Phaser | ✓ | ✓ | 动态注册/注销 | 复杂分阶段任务 |
Exchanger | ✓ | ✓ | 数据交换 | 线程间数据传递 |
2. 屏障参数配置对比
配置项 | CyclicBarrier | CountDownLatch |
初始化参数 | 等待线程数 | 需要countDown的次数 |
重用方式 | 自动重置 | 需重新创建实例 |
异常处理 | BrokenBarrierException | 无特殊异常 |
五、高级应用技巧
1. 多阶段任务控制
// 使用多个屏障实现多阶段同步
CyclicBarrier phase1 = new CyclicBarrier(3);
CyclicBarrier phase2 = new CyclicBarrier(3, ()->System.out.println("阶段2完成"));// 线程中按顺序等待
phase1.await();
// 执行阶段1任务...
phase2.await();
2. 动态线程管理
// 使用Phaser替代(JDK7+)
Phaser phaser = new Phaser(1); // 注册主线程
for (int i = 0; i < 3; i++) {phaser.register(); // 动态注册任务线程new Thread(() -> {doWork();phaser.arriveAndDeregister(); // 完成任务后注销}).start();
}
phaser.arriveAndAwaitAdvance(); // 主线程等待
3. 性能监控
// 监控屏障等待情况
System.out.println("当前等待线程数: " + barrier.getNumberWaiting());
if (barrier.isBroken()) {System.out.println("警告:屏障已被破坏!");
}
六、工程实践中的陷阱与解决方案
1. 死锁风险场景
// 错误示例:线程池大小 < 屏障要求的parties数
ExecutorService pool = Executors.newFixedThreadPool(2);
CyclicBarrier barrier = new CyclicBarrier(3); // 要求3个线程
pool.submit(() -> barrier.await()); // 永远阻塞
pool.submit(() -> barrier.await());
解决方案:
- 确保线程池大小 ≥ parties数
- 添加超时机制:
barrier.await(10, TimeUnit.SECONDS);
2. 屏障断裂处理
当某个等待线程被中断或超时,会触发BrokenBarrierException
,此时需要:
try {barrier.await();
} catch (BrokenBarrierException e) {// 1. 记录断裂原因// 2. 重置屏障或终止任务barrier.reset(); // 仅CyclicBarrier有效
}
七、性能优化技巧
1. 分层屏障设计
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 子任务组1 │ │ 子任务组2 │ │ 子任务组N │
│ (屏障A) │ │ (屏障A) │ │ (屏障A) │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘│ │ │└─────────┬────────┴────────┬─────────┘│ 全局屏障B │▼ ▼┌───────────────────┐│ 最终聚合处理 │└───────────────────┘
适用场景:大数据分片处理(如MapReduce)
2. 与ForkJoinPool结合
ForkJoinPool pool = new ForkJoinPool(4);
CyclicBarrier barrier = new CyclicBarrier(4);pool.execute(() -> {// 分治任务1barrier.await();// 合并结果...
});
八、分布式屏障扩展(ZooKeeper实现)
1. 核心原理
┌─────────────┐ ┌─────────────┐
│ 节点1 │ │ 节点2 │
│ 创建临时节点 │───>│ 监听节点变化 │
└─────────────┘ └─────────────┘│ ▲└───────┬───────┘▼┌─────────────┐│ ZooKeeper ││ /barrier │└─────────────┘
2. Java代码片段
public class DistributedBarrier {private final ZooKeeper zk;private final String barrierPath;public void await() throws Exception {zk.create(barrierPath + "/node", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);while (true) {List<String> nodes = zk.getChildren(barrierPath, false);if (nodes.size() >= REQUIRED_NODES) {break; // 所有节点就绪}Thread.sleep(100);}}
}
九、监控与调试方案
1. 关键监控指标
指标 | 采集方式 | 健康阈值 |
平均等待时间 | Barrier日志打点 + Prometheus | < 任务超时时间的20% |
屏障断裂次数 | 异常捕获统计 | 每小时 < 3次 |
线程阻塞比例 | ThreadMXBean监控 | < 线程数的30% |
2. Arthas诊断命令
# 查看屏障状态
watch java.util.concurrent.CyclicBarrier getParties returnObj
# 监控等待线程
thread -b | grep 'await'
十、与其他模式的组合应用
1. 屏障 + 生产者消费者模式
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 生产者线程 │ │ 生产者线程 │ │ 屏障 │
│ 生产数据 │───>│ 提交到队列 │───>│ 等待所有生产 │
└─────────────┘ └─────────────┘ └──────┬──────┘│
┌─────────────┐ ┌─────────────┐ ┌──────▼──────┐
│ 消费者线程 │ │ 消费者线程 │ │ 屏障释放 │
│ 开始消费 │<───│ 从队列获取 │<───│ 触发消费信号│
└─────────────┘ └─────────────┘ └─────────────┘
2. 代码示例
BlockingQueue<Data> queue = new LinkedBlockingQueue<>();
CyclicBarrier producerBarrier = new CyclicBarrier(3, () -> {System.out.println("所有生产者完成,启动消费者");startConsumers();
});// 生产者线程
void produce() {queue.put(generateData());producerBarrier.await();
}
相关文章:

并发设计模式实战系列(16):屏障(Barrier)
🌟 大家好,我是摘星! 🌟 今天为大家带来的是并发设计模式实战系列,第十六章屏障(Barrier),废话不多说直接开始~ 目录 一、核心原理深度拆解 1. 屏障的同步机制 2. 关键参数 二…...
基于深度学习的图像识别技术:从原理到应用
前言 在当今数字化时代,图像识别技术已经渗透到我们生活的方方面面,从智能手机的人脸解锁功能到自动驾驶汽车对交通标志的识别,再到医疗影像诊断中的病变检测,图像识别技术正以其强大的功能和广泛的应用前景,改变着我们…...
Linux远程管理完全指南:从网络配置到安全连接
一、网络基础配置 1. 查看IP地址与网卡信息 命令:ifconfig ifconfig # 显示所有网卡信息 ifconfig ens33 # 查看特定网卡(如ens33)详细信息 关键信息解析: inet:IPv4地址(如 192.168.1.100&am…...

算法探秘:和为K的子数组问题解析
算法探秘:和为K的子数组问题解析 一、引言 在算法的奇妙世界里,数组相关的问题总是层出不穷。“和为K的子数组”问题,看似简单,实则蕴含着丰富的算法思想和技巧。它要求我们在给定的整数数组中,找出和为特定值K的子数组个数。通过深入研究这个问题,我们不仅能提升对数组…...
Python程序打包为EXE文件的全面指南
Python程序打包为EXE文件的全面指南 Python程序打包为EXE文件是解决程序分发和环境依赖问题的有效方法。通过将Python脚本及其所有依赖项整合为单一可执行文件,用户无需安装Python解释器即可直接运行程序,极大提升了应用的便携性和用户体验。本文将深入…...

电力MOSFET的专用集成驱动电路IR2233
IR2233是IR2133/IR2233/IR2235 系列驱动芯片中的一种,是专为高电压、高速度的电力MOSFET和IGBT驱动而设计的。该系列驱动芯片内部集成了互相独立的三组板桥驱动电路,可对上下桥臂提供死区时间,特别适合于三相电源变换等方面的应用。其内部集成了独立的运算放大器可通过外部桥…...

Qt 的原理及使用(1)——qt的背景及安装
1. Qt 背景介绍 1.1 什么是 Qt Qt 是⼀个 跨平台的 C 图形⽤⼾界⾯应⽤程序框架 。它为应⽤程序开发者提供了建⽴艺术级图形 界⾯所需的所有功能。它是完全⾯向对象的,很容易扩展。Qt 为开发者提供了⼀种基于组件的开发模 式,开发者可以通过简单的拖拽…...

范式之殇-关系代数与参照完整性在 Web 后台的落寞
最近参加了一个PostgreSQL相关的茶会,感慨良多。原本话题是PostgreSQL 在 SELECT 场景中凭借其成熟的查询优化器、丰富的功能特性和灵活的执行策略,展现出显著优势。在窗口函数(Window Functions)、JOIN 优化、公共表表达式&#…...

广西某建筑用花岗岩矿自动化监测
1. 项目简介 某矿业有限公司成立于2021年,是由某建筑材料有限公司与个人共同出资成立,矿区面积0.4069平方公里,可开采筑用花岗岩、建筑用砂岩。建筑用花岗岩、建筑用砂岩可利用资源量分别为6338.69万吨、303.39万吨,设计生产规模…...

想更好应对突发网络与业务问题?需要一款“全流量”工具
目录 什么是“全流量”? 为什么“全流量”在突发问题中如此重要? 1. 抓住问题发生的“第一现场” 2. 绕开日志盲区 3. 精准应对安全威胁 实战场景下的“全流量”价值体现 实施“全流量”需要注意哪些点? 1. 数据量巨大,需…...
git的push.default配置详解
Git的push.default配置用于定义执行git push时未指定远程和分支的默认行为。以下是各选项的详解及使用场景: 1. simple(默认值,Git ≥2.0) 行为:仅推送当前分支到与其关联的上游分支(即remote-tracked分支…...

C#里创建一个MaterialDesign3的导航条
本文里主要创建如下的窗口: 在这里就是实现左边的导航窗口的列表。 第一步先要定义下面的代码: <Window x:Class="MDIXWindow.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microso…...

Oracle OCP认证考试考点详解083系列09
题记: 本系列主要讲解Oracle OCP认证考试考点(题目),适用于19C/21C,跟着学OCP考试必过。 41. 第41题: 题目 解析及答案: 关于应用程序容器,以下哪三项是正确的? A) 它可以包含单个…...
中达瑞和便携式高光谱相机:珠宝鉴定领域的“光谱之眼”
在珠宝行业中,真伪鉴定始终是核心需求。随着合成技术与优化处理手段的日益精进,传统鉴定方法逐渐面临挑战。中达瑞和推出的便携式高光谱相机,凭借其独特的“图谱合一”技术,为珠宝真假鉴定提供了科学、高效且无损的解决方案&#…...
在Star-CCM+中实现UDF并引用场数据和网格数据
在Star-CCM中实现UDF并引用场数据和网格数据 Star-CCM中的用户自定义函数(UDF)允许用户通过Java或C/C编程扩展软件功能。下面我将详细介绍如何实现UDF并引用模拟数据。 1. UDF基础实现方法 1.1 创建UDF的步骤 在Star-CCM中,右键点击"工具" → “用户函…...
用于备份的git版本管理指令
一、先下载一个git服务器软件并安装,创建一个git服务器进行备份的版本管理。 下列指令用于git常用备份: 1、强制覆盖远程仓库: git push --force origin master 2、重新指向新仓库: git remote set-url origin http://192.168.1.2…...
CI/CD面试题及答案
一、CI/CD 基础概念 1. 什么是 CI/CD?CI 和 CD 的区别是什么? 答案: CI(持续集成):开发人员提交代码后,自动构建并运行测试,确保代码集成无冲突。CD(持续交付 / 部署&am…...

如何进行室内VR全景拍摄?
如何进行室内VR全景拍摄? 室内VR全景拍摄作为先进的视觉技术,能够为用户提供沉浸式的空间体验。本文介绍如何进行室内VR全景拍摄,并阐述众趣科技在这一领域的技术支持和服务优势。 室内VR全景拍摄基础 1. 室内VR全景拍摄概述 室内VR全景拍…...

C# 综合示例 库存管理系统20 操作员管理(FormAdmin)
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的 图99A-35 操作员管理窗口设计 增加操作员或者重置密码,密码都设置为默认的“123456”,操作员可以登录系统后再修…...

[JAVAEE]HTTP协议(2.0)
响应报文格式 响应报文格式由首行,响应头(header),空行,正文(body) 组成 响应报文首行包括 1.版本号 如HTTP/1.1 2.状态码(如200) 描述了请求的结果 3.状态码描述(如OK) 首行——状态码…...

VUE+ElementUI 使用el-input类型type=“number” 时,取消右边的上下箭头
项目场景: 提示:这里简述项目相关背景: 在项目中有时候需要输入框的type“number”,这个时候,输入框的右边就会出现两个按钮,这两个按钮可以递增/递减,但是这样输入框看上去就不太美观&#x…...

计算机视觉——MedSAM2医学影像一键实现3D与视频分割的高效解决方案
引言 在乡村医院的傍晚高峰时段,扫描室内传来阵阵低沉的嗡鸣声,仿佛一台老旧冰箱的运转声。一位疲惫的医生正全神贯注地检查着当天的最后一位患者——一位不幸从拖拉机上摔下的农民,此刻正呼吸急促。CT 机器飞速旋转,生成了超过一…...

垃圾分类宣教小程序源码介绍
随着环保意识的提升,垃圾分类已成为我们生活中不可或缺的一部分。为了更好地宣传和教育大众关于垃圾分类的知识,一款基于ThinkPHP、FastAdmin和UniApp开发的垃圾分类宣教小程序应运而生。 该小程序源码结合了ThinkPHP的强大后台功能、FastAdmin的高效管…...

【wpf】12 在WPF中实现HTTP通信:封装HttpClient的最佳实践
一、背景介绍 在现代桌面应用开发中,网络通信是不可或缺的能力。WPF作为.NET平台下的桌面开发框架,可通过HttpClient轻松实现与后端API的交互。本文将以一个实际的HttpsMessages工具类为例,讲解如何在WPF中安全高效地封装HTTP通信模块。 二、…...
机器学习经典算法:用决策树原理优化新能源汽车续航能力
🔥 “用决策树重构新能源车能量大脑!算法推导+代码实战全解,续航暴增15%” 决策树算法就像我们生活中做决策的 “流程指南”,通过层层判断得出最终结论。比如你去超市买水果,站在琳琅满目的货架前,就不自觉地用上了决策树思维。首先,你可能会想 “今天想吃酸的还是甜的…...

【Hive入门】Hive安全管理与权限控制:用户认证与权限管理深度解析
目录 引言 1 Hive安全管理体系概述 2 Hive用户认证机制 2.1 Kerberos集成认证 2.1.1 Kerberos基本原理 2.1.2 Hive集成Kerberos配置步骤 2.1.3 Kerberos认证常见问题排查 2.2 LDAP用户同步 2.2.1 LDAP协议概述 2.2.2 Hive集成LDAP配置 2.2.3 LDAP与Hive用户同步架构…...

解决 Builroot 系统编译 perl 编译报错问题
本文提供一种修复 Builroot 系统编译 perl 编译报错途径 2025-05-04T22:45:08 rm -f pod/perl5261delta.pod 2025-05-04T22:45:08 /usr/bin/ln -s perldelta.pod pod/perl5261delta.pod 2025-05-04T22:45:08 /usr/bin/gcc -c -DPERL_CORE -fwrapv -fpcc-struct-return -pipe -f…...
Vue3 + Node.js 实现客服实时聊天系统(WebSocket + Socket.IO 详解)
Node.js 实现客服实时聊天系统(WebSocket Socket.IO 详解) 一、为什么选择 WebSocket? 想象一下淘宝客服的聊天窗口:你发消息,客服立刻就能看到并回复。这种即时通讯效果是如何实现的呢?我们使用 Vue3 作…...

强化学习PPO算法学习记录
1. 四个模型: Policy Model:我们想要训练的目标语言模型。我们一般用SFT阶段产出的SFT模型来对它做初始化。Reference Model:一般也用SFT阶段得到的SFT模型做初始化,在训练过程中,它的参数是冻结的。Ref模型的主要作用…...

从零开始:用PyTorch构建CIFAR-10图像分类模型达到接近1的准确率
为了增强代码可读性,代码均使用Chatgpt给每一行代码都加入了注释,方便大家在本文代码的基础上进行改进优化。 本文是搭建了一个稍微优化了一下的模型,训练200个epoch,准确率达到了99.74%,简单完成了一下CIFAR-10数据集…...