CyclicBarrier 源码

发布时间:2026/7/10 1:30:47

CyclicBarrier 源码
成员变量// 独占可重入锁所有操作加锁保证线程安全privatefinalReentrantLocklocknewReentrantLock();// 条件变量所有到达栅栏的线程阻塞在此privatefinalConditiontriplock.newCondition();// 总等待线程数固定不变finalprivatefinalintparties;// 最后一个线程到达时执行的回调任务privatefinalRunnablebarrierCommand;// 当前代次实例privateGenerationgenerationnewGeneration();// 当前剩余等待线程数每轮从parties递减到0privateintcount;构造方法// 带屏障任务publicCyclicBarrier(intparties,RunnablebarrierAction){if(parties0)thrownewIllegalArgumentException();this.partiesparties;this.countparties;this.barrierCommandbarrierAction;}// 无屏障任务委托上面构造器publicCyclicBarrier(intparties){this(parties,null);}GenerationprivatestaticclassGeneration{booleanbrokenfalse;// true本轮栅栏损坏}awaitpublicintawait()throwsInterruptedException,BrokenBarrierException{try{returndowait(false,0L);}catch(TimeoutExceptiontoe){thrownewError(toe);// timedfalse不会触发超时不可能走到这里}}dowaitprivateintdowait(booleantimed,longnanos)throwsInterruptedException,BrokenBarrierException,TimeoutException{finalReentrantLocklockthis.lock;// 加锁串行修改共享变量lock.lock();try{finalGenerationggeneration;if(g.broken)thrownewBrokenBarrierException();if(Thread.interrupted()){breakBarrier();thrownewInterruptedException();}// 等待计数-1index是当前线程到达序号最后一个为0intindex--count;// 所有线程全部抵达触发栅栏if(index0){// trippedbooleanranActionfalse;try{finalRunnablecommandbarrierCommand;if(command!null)command.run();ranActiontrue;// 重置栅栏开启下一轮nextGeneration();return0;}finally{if(!ranAction)breakBarrier();// 屏障任务执行异常栅栏损坏}}// loop until tripped, broken, interrupted, or timed outfor(;;){try{if(!timed)trip.await();elseif(nanos0L)nanostrip.awaitNanos(nanos);}catch(InterruptedExceptionie){if(ggeneration!g.broken){breakBarrier();throwie;}else{Thread.currentThread().interrupt();}}if(g.broken)thrownewBrokenBarrierException();if(g!generation)// 代次更新说明本次 count 已经为 0栅栏放行返回序号returnindex;if(timednanos0L){// 超时未集齐线程破坏栅栏抛超时异常breakBarrier();thrownewTimeoutException();}}}finally{lock.unlock();}}nextGenerationprivatevoidnextGeneration(){// 1. 唤醒当前代所有阻塞在trip条件队列的线程trip.signalAll();// 2. 重置等待计数器为初始总线程数countparties;// 3. 新建Generation实例切换到全新一代旧代作废generationnewGeneration();}breakBarrierprivatevoidbreakBarrier(){// 1. 标记当前代栅栏损坏generation.brokentrue;// 2. 重置计数器countparties;// 3. 唤醒所有等待线程trip.signalAll();}总结线程调用 barrier.await() ↓ dowait(timedfalse, nanos0) ↓ lock.lock() → 抢占独占锁 ↓ 读取当前代 Generation g generation ├─ if g.broken → 抛 BrokenBarrierExceptionfinally释放锁 └─ 校验当前线程是否中断 Thread.interrupted() ├─ 是 → breakBarrier() 抛 InterruptedException释放锁 └─ 否 → count count - 1得到当前index ├─────────────────────┬ ↓ ↓ index 0最后线程 index ! 0普通等待线程 ↓ ↓ 执行 barrierCommand 进入 for(;;) 循环阻塞 │ │ │ │→ trip.await() │ │ │ ↓被signalAll唤醒后重新竞争lock锁 │ │ │ ├─ g ! generation → 正常return index ↓ 任务执行成功 → nextGeneration() │ ↓ │ trip.signalAll() 唤醒所有条件队列线程 │ count重置为parties │ new Generation() 切换代次 ↓ finally 释放锁 lock.unlock()

相关新闻

拍摄前先定脚本

拍摄前先定脚本

2026/7/10 1:30:47

很多企业拍短视频, 常常是到了现场才临时想怎么拍。 场景有了,人员也到了,但镜头怎么走、谁来说、重点放在哪, 一开始没有设计清楚。 最后素材拍了一堆,剪辑时却发现内容没有主线, 成片看起来像花絮&#x…

Bard-API工具集成实战:让大语言模型调用Google服务执行复杂任务

Bard-API工具集成实战:让大语言模型调用Google服务执行复杂任务

2026/7/10 1:30:47

1. 项目概述:当Bard学会“使用工具” 如果你和我一样,一直在关注大语言模型(LLM)的进化,那么“工具调用”这个能力,绝对是近一年来最让人兴奋的突破之一。它让模型从一个“博学的聊天者”,变成…

详解AUTOSAR:CanSM通信模式状态机与BusOff恢复机制(理论篇—12)

详解AUTOSAR:CanSM通信模式状态机与BusOff恢复机制(理论篇—12)

2026/7/10 1:30:47

CAN 通道从睡眠到可通信,不只是把控制器置为 STARTED。控制器、收发器、CanIf PDU Mode、ComM 模式、BswM 状态、DEM 事件都要按顺序变化;其中任何一个异步模式指示缺失,都可能让通信栈停在过渡状态。CanSM 的职责就是把 ComM 的网络通信模式请求翻译成 CAN 硬件和 CanIf 的…

Ultralytics Docker镜像选型与YOLO训练部署实战指南

Ultralytics Docker镜像选型与YOLO训练部署实战指南

2026/7/10 3:00:51

1. 为什么是 Ultralytics Docker?——不是“又一个容器教程”,而是解决实际训练卡点的钥匙Ultralytics Docker 不是单纯把 YOLOv8/YOLOv10 搬进容器里走个过场,它是我在过去三年带团队落地 27 个工业视觉项目时,反复验证后沉淀下来…

OpenCV C++ 贾志刚教程:从环境搭建到DNN部署的完整指南

OpenCV C++ 贾志刚教程:从环境搭建到DNN部署的完整指南

2026/7/10 3:00:51

1. 项目概述:为什么选择OpenCV C?如果你正在计算机视觉领域摸索,或者想从Python转向更底层的实现,那么“OpenCV C 贾志刚教程”这个标题对你来说应该不陌生。它背后指向的,是国内很多开发者入门OpenCV C时绕不开的一套…

技术直觉退化了?不,是换了一种用法

技术直觉退化了?不,是换了一种用法

2026/7/10 3:00:51

虚,从一次Code Review开始 第四周周一早上,陈钊做了一件已经很久没做了的事——打开IDE,认真看代码。 起因是小李上周提了一个PR,改动量不小,涉及到支付模块的核心链路。按照陈钊以前的习惯,这种级别的PR他…

在Python中,什么是GIL?

在Python中,什么是GIL?

2026/7/10 3:00:51

📖 GIL 是什么? GIL 是 Global Interpreter Lock(全局解释器锁)的缩写。 简单来说,它是 Python 官方解释器(CPython,也就是你平时下载的 Python)中的一个互斥锁(Mutex&…

KMP 算法 next 数组:5 步手算推导法与 3 种代码实现对比(C/Java/Python)

KMP 算法 next 数组:5 步手算推导法与 3 种代码实现对比(C/Java/Python)

2026/7/10 3:00:51

KMP 算法 next 数组:5 步手算推导法与 3 种代码实现对比(C/Java/Python)在字符串匹配的世界里,KMP算法犹如一位优雅的剑客,以其独特的「部分匹配表」技巧绕过了暴力匹配的蛮力消耗。本文将深入剖析KMP算法的核心——ne…

肖特基二极管 DSK34 选型实战:BUCK 续流 3A 场景下的 0.3V 压降分析

肖特基二极管 DSK34 选型实战:BUCK 续流 3A 场景下的 0.3V 压降分析

2026/7/10 2:50:50

肖特基二极管 DSK34 选型实战:BUCK 续流 3A 场景下的 0.3V 压降分析在开关电源设计中,BUCK 拓扑的高效续流路径选择往往决定了整机性能的边界。当电感电流需要快速续流时,肖特基二极管因其超低正向压降和快速恢复特性成为首选。本文将以 Vish…

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南

2026/7/9 19:40:56

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gi…

6个月转型AI工程师:实战路径与核心技能

6个月转型AI工程师:实战路径与核心技能

2026/7/9 18:28:30

1. 项目概述:6个月转型AI工程师的可行性路径在2023年大模型技术爆发的背景下,AI工程师岗位需求同比增长217%(LinkedIn数据)。不同于传统算法工程师需要3-5年培养周期,现代AI工程师更侧重工程化落地能力。我在硅谷科技公…

YOLOv5模型剪枝与量化实战:边缘设备部署优化

YOLOv5模型剪枝与量化实战:边缘设备部署优化

2026/7/8 14:04:34

1. 项目背景与核心价值在计算机视觉领域,YOLOv5因其出色的实时检测性能成为工业界宠儿。但当我们尝试将其部署到边缘设备(如树莓派、Jetson Nano或手机终端)时,立刻会遇到两个致命问题:模型体积庞大(原始YO…

终极原神FPS解锁器完整指南:轻松突破60帧限制

终极原神FPS解锁器完整指南:轻松突破60帧限制

2026/7/10 0:00:42

终极原神FPS解锁器完整指南:轻松突破60帧限制 【免费下载链接】genshin-fps-unlock unlocks the 60 fps cap 项目地址: https://gitcode.com/gh_mirrors/ge/genshin-fps-unlock 原神FPS解锁器是一款专为《原神》玩家设计的开源工具,通过先进的Wri…

YesPlayMusic:如何用高颜值播放器重塑你的网易云音乐体验?[特殊字符]

YesPlayMusic:如何用高颜值播放器重塑你的网易云音乐体验?[特殊字符]

2026/7/10 0:00:42

YesPlayMusic:如何用高颜值播放器重塑你的网易云音乐体验?🎵 【免费下载链接】YesPlayMusic 高颜值的第三方网易云播放器,支持 Windows / macOS / Linux :electron: 项目地址: https://gitcode.com/gh_mirrors/ye/YesPlayMusic…

从零实现红黑树:手写C++的set与map容器

从零实现红黑树:手写C++的set与map容器

2026/7/10 0:00:42

1. 项目概述:从STL容器到自研轮子在C的日常开发中,std::set和std::map是我们再熟悉不过的伙伴了。它们一个负责管理不重复的集合,一个负责维护键值对映射,底层都依赖一颗高效的红黑树来保证数据的有序性和操作的性能。但你是否曾想…