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

Java 并发原子类完全指南:Atomic 全家桶、CAS/JMM、ABA、LongAdder、源码阅读路线与经典实战

多线程编程中count这样简单的操作都不是线程安全的。用synchronized能解决问题但锁会带来阻塞和上下文切换开销。java.util.concurrent.atomic包提供了一套基于 CASCompare-And-Swap的无锁并发工具在“单变量竞争”场景下能写出既简洁又高性能的并发代码。本文从“Atomic 全家桶有哪些、怎么用、怎么选”切入深入讲清 CAS 自旋与线性化点、JMM/happens-before 语义、引用更新中的 ABA 问题及其解决对比AtomicLong与LongAdder在热点计数下的性能取舍并给出源码阅读路线、常见错误写法对照与实战代码。适用于 Java 与 Android 开发者。1. 原子类解决什么问题多线程下“读-改-写”不是原子操作count会丢更新。锁能解决但会带来阻塞与上下文切换成本。Atomic 通过 CAS 在大量“单变量竞争”场景下提供无锁的正确更新。2.java.util.concurrent.atomic全家桶清单速查表这些类属于JDK 标准库Java 可用Android 也提供差异多在版本与底层实现细节。2.1 基础数值/布尔类名说明AtomicBoolean原子布尔值AtomicInteger原子整型AtomicLong原子长整型2.2 引用与数组类名说明AtomicReferenceV原子引用AtomicReferenceArrayE原子引用数组AtomicIntegerArray原子整型数组AtomicLongArray原子长整型数组2.3 ABA 防护引用增强类名说明AtomicStampedReferenceV引用 版本号stampAtomicMarkableReferenceV引用 标记位mark2.4 字段更新器对对象字段做 CAS类名说明AtomicIntegerFieldUpdaterT整型字段更新器AtomicLongFieldUpdaterT长整型字段更新器AtomicReferenceFieldUpdaterT,V引用字段更新器2.5 高并发累加/归约类名说明LongAdder/DoubleAdder高并发累加器LongAccumulator/DoubleAccumulator高并发自定义归约3. Atomic 最常用 API记住这些就够用操作类型方法读写get()/set(x)CAScompareAndSet(expect, update)数值增减incrementAndGet()/getAndIncrement()/addAndGet(delta)弱写lazySet(x)后文解释4. 核心原理CAS、自旋与线性化点4.1 CAS 是什么CASCompare-And-Set当且仅当当前值等于期望值expect时原子更新为update并返回成功/失败。4.2 CAS 循环长什么样for(;;){intprevatomic.get();intnextprev1;if(atomic.compareAndSet(prev,next)){returnnext;}}4.3 ASCII 示意图线性化点在哪里Atomic 操作对外看起来“像瞬间发生”那个瞬间就是CAS 成功线程A: 读 prev10 计算 next11 CAS(10-11) 成功 ← 线性化点 线程B: 读 prev10 计算 next11 CAS(10-11) 失败 重试...5. 关键补全JMM / happens-before /lazySet的正确直觉5.1get/set可类比volatile读写原子类内部的值通常是volatile字段因此get()≈volatile读可见性set(x)≈volatile写可见性 必要的有序性5.2lazySet(x)最终可见但不承诺立刻适合“发布型写入”不要求其他线程马上看到通过更弱的写入语义降低开销经验拿不准就用set业务代码里lazySet往往不是必需品6. 经典场景与代码可直接复用6.1 只执行一次AtomicBooleanimportjava.util.concurrent.atomic.AtomicBoolean;publicclassOnce{privatefinalAtomicBooleandonenewAtomicBoolean(false);publicvoidrunOnce(Runnabler){if(done.compareAndSet(false,true)){r.run();}}}6.2 并发计数器AtomicLongimportjava.util.concurrent.atomic.AtomicLong;publicclassCounter{privatefinalAtomicLongcountnewAtomicLong();publiclonginc(){returncount.incrementAndGet();}publiclongadd(longdelta){returncount.addAndGet(delta);}publiclongvalue(){returncount.get();}}6.3 配置/状态整体替换AtomicReference 不可变对象importjava.util.concurrent.atomic.AtomicReference;publicclassConfigHolder{staticfinalclassConfig{finalinttimeoutMs;finalbooleanenabled;Config(inttimeoutMs,booleanenabled){this.timeoutMstimeoutMs;this.enabledenabled;}}privatefinalAtomicReferenceConfigrefnewAtomicReference(newConfig(1000,true));publicConfigget(){returnref.get();}publicvoidupdate(inttimeoutMs,booleanenabled){ref.set(newConfig(timeoutMs,enabled));}}6.4 Atomic CAS 状态机通用importjava.util.concurrent.atomic.AtomicInteger;publicclassTaskStateMachine{privatestaticfinalintNEW0;privatestaticfinalintRUNNING1;privatestaticfinalintSUCCESS2;privatestaticfinalintFAILED3;privatefinalAtomicIntegerstatenewAtomicInteger(NEW);publicbooleanstart(){returnstate.compareAndSet(NEW,RUNNING);}publicbooleansucceed(){returnstate.compareAndSet(RUNNING,SUCCESS);}publicbooleanfail(){returnstate.compareAndSet(RUNNING,FAILED);}publicintgetState(){returnstate.get();}}7. 关键陷阱ABA配图 解决7.1 ABA 是什么CAS 只看“现在是不是 A”。如果经历 A→B→ACAS 仍会认为“没变过”。7.2 ASCII 示意图ABA 的“历史被抹掉”t0: 内存值 A 线程1: 读到 A准备 CAS(A-C) 线程2: 把 A 改成 B 线程2: 又把 B 改回 A 线程1: CAS(A-C) 成功 ← 线程1以为“期间没变”但其实变过7.3AtomicStampedReference用版本号解决importjava.util.concurrent.atomic.AtomicStampedReference;publicclassAbaFix{privatefinalAtomicStampedReferenceStringrefnewAtomicStampedReference(A,0);publicbooleanupdateAtoB(){int[]stampHoldernewint[1];Stringvref.get(stampHolder);intstampstampHolder[0];returnref.compareAndSet(v,B,stamp,stamp1);}}7.4AtomicMarkableReference标记位更轻当你只需要“是否删除/是否有效”的布尔标记用 mark 就够了。8. 性能关键点AtomicLongvsLongAdder热点计数必看8.1AtomicLong是单点竞争所有线程 - CAS 同一个 value 竞争越大 - 失败越多 - 自旋越多 - 越慢8.2LongAdder分片降低冲突线程们分散更新多个 cell cell[0] cell[1] cell[2] ... 最后 sum() 求和示例importjava.util.concurrent.atomic.LongAdder;publicclassHotCounter{privatefinalLongAdderaddernewLongAdder();publicvoidinc(){adder.increment();}publiclongvalue(){returnadder.sum();}}结论监控/统计/埋点这类热点计数优先LongAdder需要强一致读写语义的场景AtomicLong更直接9. 字段更新器与原子数组什么时候用9.1Atomic*FieldUpdater减少包装对象开销importjava.util.concurrent.atomic.AtomicIntegerFieldUpdater;publicclassNode{volatileintstate;privatestaticfinalAtomicIntegerFieldUpdaterNodeSTATEAtomicIntegerFieldUpdater.newUpdater(Node.class,state);publicbooleantrySet(intexpect,intupdate){returnSTATE.compareAndSet(this,expect,update);}}9.2Atomic*Array分桶统计常用保证单个元素原子更新如果你要“一次更新多个桶并保持一致”仍需要更高层的设计锁/不可变整体等。10. 源码阅读路线最省时间版不同 JDK/Android 版本可能用Unsafe或VarHandle但语义一致。建议顺序AtomicInteger看value、compareAndSet、incrementAndGetCAS 循环AtomicReference引用 CAS 与 ABA 风险AtomicStampedReference/AtomicMarkableReference组合比较与更新LongAddercell 分片与sum()你只要抓三件事值字段是谁通常 volatileCAS 改的是哪个字段失败后如何重试/退避11. 常见错误写法 vs 正确写法强烈建议收藏区11.1 错误用volatile当原子自增volatileintcount0;publicvoidinc(){count;// 仍然不安全}正确二选一用原子类importjava.util.concurrent.atomic.AtomicInteger;AtomicIntegercountnewAtomicInteger();publicvoidinc(){count.incrementAndGet();}或者用锁保护复合操作当你还有别的共享状态要一起保护时更合适。11.2 错误想“多变量一起原子”却分别用多个 AtomicAtomicIntegeranewAtomicInteger();AtomicIntegerbnewAtomicInteger();publicvoidupdateBoth(){a.incrementAndGet();b.incrementAndGet();// 这两步之间可能被别的线程观察到“中间态”}正确思路常用两种用锁把临界区包起来最直观或者把 (a,b) 封装成不可变对象用AtomicReferenceState整体替换读多写少时很优雅示例整体替换importjava.util.concurrent.atomic.AtomicReference;publicclassPairState{staticfinalclassState{finalinta,b;State(inta,intb){this.aa;this.bb;}}privatefinalAtomicReferenceStaterefnewAtomicReference(newState(0,0));publicvoidincBoth(){for(;;){Stateprevref.get();StatenextnewState(prev.a1,prev.b1);if(ref.compareAndSet(prev,next)){return;}}}publicStateget(){returnref.get();}}11.3 错误热点计数还在用AtomicLong高并发下退化AtomicLongqpsnewAtomicLong();publicvoidhit(){qps.incrementAndGet();// 高竞争下可能大量自旋失败}正确统计类计数importjava.util.concurrent.atomic.LongAdder;LongAdderqpsnewLongAdder();publicvoidhit(){qps.increment();}publiclongqps(){returnqps.sum();}12. 选型总结速查表场景推荐选择只要可见性volatile单变量原子更新AtomicBoolean/AtomicInteger/AtomicLong热点计数高并发统计LongAdder整体替换状态/配置AtomicReference不可变对象担心 ABA 问题AtomicStampedReference/AtomicMarkableReference大量对象字段要原子操作Atomic*FieldUpdater分桶/数组统计Atomic*Array13. 结语Atomic 的关键不是“背 API”而是掌握三件事CAS 成功就是生效点、JMM 可见性语义要有直觉、以及高竞争下懂得换LongAdder或改变结构。把问题收敛到“单点状态”时Atomic 往往能写出既简洁又高性能的并发代码。文末小贴士1 分钟速查清单CAScompareAndSet(expect, update)成功那一刻就是操作生效点JMMget()有 volatile 读语义set()有 volatile 写语义ABA担心就上AtomicStampedReference带版本号热点计数高并发下LongAdder完胜AtomicLong多变量原子要么用锁要么用AtomicReference包不可变对象状态机用AtomicInteger配合常量状态值CAS 驱动转移相关推荐深入理解 AQS 和 CAS 原理Synchronized 和 ReentrantLock

相关文章:

Java 并发原子类完全指南:Atomic 全家桶、CAS/JMM、ABA、LongAdder、源码阅读路线与经典实战

多线程编程中,count 这样简单的操作都不是线程安全的。用 synchronized 能解决问题,但锁会带来阻塞和上下文切换开销。java.util.concurrent.atomic 包提供了一套基于 CAS(Compare-And-Swap)的无锁并发工具,在“单变量…...

手把手教你用Python和MATLAB生成标准SVS文件(从numpy数组到多级金字塔)

从Numpy数组到多级金字塔:Python与MATLAB生成SVS文件的实战指南 在数字病理领域,全切片图像(WSI)的生成与共享已成为研究协作的关键环节。许多研究者面临一个共同挑战:如何将处理后的numpy数组(如分割结果或合成图像)转…...

Phi-4-reasoning-vision-15B在研发协作中的应用:代码IDE截图理解与问题定位

Phi-4-reasoning-vision-15B在研发协作中的应用:代码IDE截图理解与问题定位 1. 引言:研发协作中的视觉理解需求 在软件开发团队中,工程师们每天都要处理大量代码截图和IDE界面。当遇到问题时,最常见的做法是把报错截图或代码片段…...

逆变器核心技术解析:锁相环(PLL)在并网系统中的应用与优化

1. 锁相环(PLL)在并网逆变器中的核心作用 想象一下你正在参加一场合唱比赛,如果每个人的节奏都不一致,整个表演就会变得杂乱无章。并网逆变器面临的也是类似的问题——它需要与电网保持完美的"节奏同步",而这个"指挥家"就…...

Z-Image-Turbo-辉夜巫女实战教程:GPU算力弹性伸缩——按需加载LoRA模型

Z-Image-Turbo-辉夜巫女实战教程:GPU算力弹性伸缩——按需加载LoRA模型 1. 快速了解Z-Image-Turbo-辉夜巫女 Z-Image-Turbo-辉夜巫女是基于Z-Image-Turbo模型的LoRA版本,专门优化用于生成辉夜巫女风格图片的AI模型。这个模型通过Xinference框架部署&am…...

Beautiful Soup

什么是Beautiful Soup 官网推荐现在的项目使用BeautifulSoup4 (BeautifulSoup 4版本,简称为bs4)开发。bs4是一个HTML/XML的解析器,主要的功能是解析和提取HTML/XML数据。 bs4不仅支持CSS选择器,而且支持Python标准库…...

Intv_AI_MK11与Claude协同实战:构建多模型AI应用开发平台

Intv_AI_MK11与Claude协同实战:构建多模型AI应用开发平台 1. 混合AI模型的应用价值 在AI应用开发领域,单一模型往往难以满足复杂业务需求。就像一支足球队需要不同位置的球员配合一样,将Intv_AI_MK11与Claude等模型协同部署,能够…...

Qwen3.5-9B-AWQ-4bit Proteus电路仿真辅助:原理图分析与代码生成

Qwen3.5-9B-AWQ-4bit Proteus电路仿真辅助:原理图分析与代码生成 1. 电子工程师的新助手 作为一名电子工程师,你是否经常遇到这样的场景:面对复杂的电路原理图,需要花费大量时间分析各个模块的功能;或者在Proteus中设…...

Git-RSCLIP多场景落地:生态环境监测中‘红树林退化’语义识别案例

Git-RSCLIP多场景落地:生态环境监测中"红树林退化"语义识别案例 1. 项目背景与需求 红树林作为重要的海岸带生态系统,具有防风消浪、净化水质、维持生物多样性等重要生态功能。然而近年来,由于人类活动和环境变化,全球…...

Qwen-Image-Edit-2511在云端:集成显卡/Mac也能流畅运行的AI修图方案

Qwen-Image-Edit-2511在云端:集成显卡/Mac也能流畅运行的AI修图方案 1. 为什么选择云端部署Qwen-Image-Edit-2511? 1.1 硬件限制的突破性解决方案 传统AI图像编辑工具对硬件的高要求一直是普通用户的痛点。Qwen-Image-Edit-2511作为最新一代多模态编辑…...

基于Matlab实现 IEEE33节点配电网系统simulink仿真模型,并配套前推回代法潮流计算程序

基于Matlab实现 IEEE33节点配电网系统simulink仿真模型,并配套前推回代法潮流计算程序。 改进的IEEE33节点,潮流计算,电压分析,可自行加风机光伏,接电动机负载。 结果图如图所展示,附带IEEE33节点数据MATLA…...

M2LOrder模型赋能软件测试:用例生成与缺陷预测实践

M2LOrder模型赋能软件测试:用例生成与缺陷预测实践 最近和几个做测试的朋友聊天,大家普遍吐槽,现在软件迭代越来越快,留给测试的时间却越来越短。需求文档刚定稿,开发那边代码就快写完了,测试用例还没设计…...

从直觉到算法:贝叶斯思维的技术底层与工程实现督

背景 在软件开发的漫长旅途中,"构建"这个词往往让人又爱又恨。爱的是,一键点击,代码变成产品,那是程序员最迷人的时刻;恨的是,维护那一堆乱糟糟的构建脚本,简直是噩梦。 在很多项目中…...

算术运算符(i++与++i)

i与i在独立使用时结果一致;作为表达式使用时:j 8(1)k j 等于 j j1,再k j 。先自增,再赋值 ,j9,k9(2) k j 等于 k j,再j j1 。先赋值&#…...

从零解析SHA-1:一个160位哈希的诞生之旅

1. 从原材料到成品:SHA-1的工厂流水线 想象你是一家精密零件加工厂的厂长,每天要处理各种形状不规则的金属原料(原始数据),最终需要生产出标准化的160位产品(哈希值)。SHA-1算法就像这条全自动生…...

别再死记硬背Payload了:用BUUCTF Basic靶场案例拆解漏洞利用的本质逻辑

别再死记硬背Payload了:用BUUCTF Basic靶场案例拆解漏洞利用的本质逻辑 在网络安全领域,很多学习者都会陷入一个误区:过度依赖现成的Payload和工具脚本,而忽视了漏洞利用背后的核心逻辑。这种学习方式虽然能快速解决特定题目&…...

OpenClaw调用Qwen3-32B镜像成本实测:RTX4090D长任务Token消耗分析

OpenClaw调用Qwen3-32B镜像成本实测:RTX4090D长任务Token消耗分析 1. 为什么关注OpenClaw的Token消耗问题 第一次用OpenClaw完成文件整理任务时,我被账单吓了一跳——短短10分钟的操作消耗了近3万Token。这让我意识到:自动化助手的长期使用…...

系统分析师论文模版分析

系统分析师论文模板深度分析 系统分析师考试的论文(科目三)是一道 2500~3000字 的论述题,要求结合实际项目经验,围绕给定主题展开分析。论文的评分维度包括:切合题意、理论深度、实践细节、逻辑结构、语言表达。以下是对典型论文模板的结构拆解与写作要点分析。 一、论文…...

GPU算力优化实践:Pixel Epic智识终端显存配额与逻辑发散调参详解

GPU算力优化实践:Pixel Epic智识终端显存配额与逻辑发散调参详解 1. 引言:当像素冒险遇上AI研究 在科研领域,我们常常面临一个两难选择:要么追求严谨性而牺牲创造力,要么放飞思维却失去逻辑性。Pixel Epic智识终端通…...

LFM2.5-1.2B-Thinking-GGUF效果展示:32K上下文下跨段落信息关联与归纳能力实测

LFM2.5-1.2B-Thinking-GGUF效果展示:32K上下文下跨段落信息关联与归纳能力实测 1. 模型核心能力展示 1.1 32K上下文处理实测 LFM2.5-1.2B-Thinking-GGUF最突出的能力是其32K超长上下文处理能力。在实际测试中,我们输入了一篇约2万字的技术文档&#x…...

OpenClaw跨模型路由:按图片类型分配Qwen3.5-9B与本地LLM

OpenClaw跨模型路由:按图片类型分配Qwen3.5-9B与本地LLM 1. 为什么需要跨模型路由 去年我在处理大量技术文档截图时,发现一个有趣的现象:流程图和表格类图片需要强大的多模态理解能力,而纯文字截图往往只需要基础的OCR功能。当时…...

基于YOLOV5的手势识别检测系统

基于YOLOV5的手势识别检测系统项目介绍: 软件:PycharmAnaconda 环境:python3.8 opencv_python PyQt5文件: 1.完整程序文件(.py等) 2.UI界面源文件、图标(.ui、.qrc、.py等) 3.测试图…...

全国首个!深开鸿与前海供电公司打造的数据中心电鸿变配电室正式投运

不久前,我国首个专为数据中心设计的用户专用电力开源鸿蒙变配电室在深圳前海投入使用。该项目由深开鸿与深圳前海供电公司打造,以电鸿物联操作系统为核心,融合感知终端、电力物联、数字孪生、人工智能四大能力,为前海信息枢纽大厦…...

Qwen3-Reranker完整指南:支持Markdown/HTML文档解析的增强版方案

Qwen3-Reranker完整指南:支持Markdown/HTML文档解析的增强版方案 1. 引言:重新定义文档检索的精准度 在日常工作中,你是否遇到过这样的困扰:用关键词搜索文档时,系统返回的结果看似相关,实际上却偏离了你…...

基于Qt框架的桌面应用开发:集成nli-distilroberta-base实现本地文本分析工具

基于Qt框架的桌面应用开发:集成nli-distilroberta-base实现本地文本分析工具 1. 引言:当桌面应用遇上NLP模型 最近在开发一个跨平台的文本分析工具时,遇到了一个有趣的需求:如何让传统桌面应用具备自然语言理解能力?…...

仅限首批内测用户掌握的PyTorch 3.0图优化黑盒(torch._dynamo.eval_frame._optimize_ctx),3行代码解锁Graph-Level Profiling

第一章:PyTorch 3.0 静态图分布式训练性能调优指南PyTorch 3.0 引入了原生静态图编译能力(通过 torch.compile(..., dynamicFalse) 显式启用),结合 DistributedDataParallel(DDP)与 FSDP,可在多…...

005、边缘AI与嵌入式智能:芯片、算法与场景的融合

005、边缘AI与嵌入式智能:芯片、算法与场景的融合 昨天深夜调一个图像分类模型,在PC上精度还有92%,部署到开发板上直接掉到60%不到。板子的推理输出全是乱码,散热片烫得能煎鸡蛋。这种问题在边缘AI项目里太典型了——实验室的算法…...

跨平台兼容秘诀:OpenClaw在Linux对接百川2-13B-4bits模型全记录

跨平台兼容秘诀:OpenClaw在Linux对接百川2-13B-4bits模型全记录 1. 为什么选择Linux环境部署OpenClaw 去年夏天,当我第一次尝试在Ubuntu服务器上部署OpenClaw时,完全没料到这会成为我最折腾也最有成就感的开源项目实践。作为长期使用macOS的…...

Qwen3-ASR-1.7B应用案例:在线面试平台→实时语音转文字+回答时长分析

Qwen3-ASR-1.7B应用案例:在线面试平台→实时语音转文字回答时长分析 想象一下,你是一家快速发展的科技公司HR,每天要面试几十位候选人。面试官一边提问,一边手忙脚乱地记录,生怕漏掉关键信息。面试结束后,…...

2026年本地录音转文字工具实测对比算准确率算本地处理速度,差距竟然这么大

对比了多款本地录音转文字工具,听脑AI是综合体验最好的,没有之一。我自己做内容创作天天跟AI工具打交道,最近半个月一堆教育圈的朋友找我要靠谱的转写工具——备课要整理公开课素材,教研会要记讨论内容,开完家长会还要…...