0

0

在Java里Atomic类解决了什么问题_Java原子操作类库解析

P粉602998670

P粉602998670

发布时间:2026-01-23 09:02:02

|

105人浏览过

|

来源于php中文网

原创

AtomicInteger等类解决单变量“读-改-写”竞态问题,不替代锁或解决所有并发问题;i++非原子致丢失更新,volatile无法修复;CAS实现原子操作,但不支持多变量事务或复杂条件逻辑。

在java里atomic类解决了什么问题_java原子操作类库解析

Java 的 AtomicIntegerAtomicLong 等类,解决的是**多线程环境下对单个变量做“读-改-写”操作时的竞态条件问题**,而不是替代锁或解决所有并发问题。

为什么 i++ 在多线程下会出错

看似简单的 i++ 实际包含三步:读取当前值 → 加 1 → 写回内存。若两个线程同时执行,可能都读到旧值(比如 5),各自加 1 后都写回 6,结果丢失一次更新。

这种非原子性行为无法靠 volatile 修复——它只保证可见性,不保证操作的原子性。

  • volatile int i = 0; 不能防止 i++ 的中间步骤被穿插
  • AtomicInteger i = new AtomicInteger(0);i.incrementAndGet() 是底层用 CPU 的 CAS(Compare-And-Swap)指令实现的单指令原子操作
  • 不是所有平台都支持 CAS,但 HotSpot JVM 在 x86/ARM 上已通过 lock cmpxchgldxr/stxr 等指令兜底

Atomic 类能做什么,不能做什么

它们适用于「单变量、无依赖、无副作用」的原子更新场景,比如计数器、序列号生成、状态标志位切换。

立即学习Java免费学习笔记(深入)”;

一旦涉及多个变量联动(如转账:A 减、B 增),或需要复合逻辑判断(如“只有余额 > 100 才扣款”),AtomicXxx 就力不从心了——它不提供条件式多步原子操作,也没有内置重试机制。

  • ✅ 支持:自增、自减、CAS 设置、getAndSet、getAndUpdate、updateAndGet
  • ❌ 不支持:跨字段事务、阻塞等待、公平性控制、超时重试
  • ⚠️ 注意:getAndUpdateupdateAndGet 接收的 UnaryOperator 函数体里不应有 I/O、锁或耗时操作,否则会卡住 CAS 自旋

AtomicReference 与对象引用的“原子性”边界

AtomicReference 保证的是「引用本身」的读写原子性,不是它指向的对象内部状态的线程安全。

比如用 AtomicReference> 存一个 ArrayList,你用 compareAndSet 替换整个引用没问题;但若调用 get().add("x"),这个 add 操作仍需额外同步——因为 ArrayList 本身不是线程安全的。

  • 常见误用:atomicRef.get().size() 返回后,对象可能已被其他线程修改,结果不可靠
  • 正确姿势:尽量把状态封装进不可变对象,再用 AtomicReference 做整体替换
  • 复杂状态变更建议配合 StampedLockReadWriteLock,而非强行拆成多个 Atomic 字段

性能开销和 ABA 问题的真实影响

CAS 自旋在低竞争时比锁快很多,但高竞争下可能反复失败重试,反而更耗 CPU。JVM 对 AtomicXxx 有专门优化(如内联、消除冗余屏障),所以不要自己用 Unsafe 模拟。

ABA 问题确实存在:变量从 A→B→A,CAS 误判为“没变过”,但实际上中间状态已改变。但现实中绝大多数场景(计数器、开关标志)根本不在乎中间是否绕过 B;真需要严格版本控制的,应使用 AtomicStampedReference 或直接上 LongAdder / ConcurrentHashMap 等更高层工具

  • 除非你在写无锁/队列这类底层结构,否则基本不用操心 ABA
  • LongAdder 在高并发计数场景比 AtomicLong 更高效,但它不提供精确的实时值(最终一致性)
  • 别为了“看起来更原子”而滥用 AtomicBoolean 控制流程——有时一个 synchronized 块更清晰、更易维护

真正难的从来不是选哪个 Atomic 类,而是判断「这里到底需不需要原子性」,以及「原子性边界划在哪」——变量级?对象级?还是业务语义级?

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

844

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

742

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

740

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

400

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

431

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16926

2023.08.03

菜鸟裹裹入口以及教程汇总
菜鸟裹裹入口以及教程汇总

本专题整合了菜鸟裹裹入口地址及教程分享,阅读专题下面的文章了解更多详细内容。

0

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.8万人学习

C# 教程
C# 教程

共94课时 | 7.3万人学习

Java 教程
Java 教程

共578课时 | 49.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号