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

Java 原子类详解

目录
  • Java 原子类详解
    • 一、基本类型原子类
    • 二、数组原子类
    • 三、引用原子类
      • ABA 问题图示
    • 四、字段更新器
    • 五、累加器(JDK 8+)
    • 六、核心对比
      • AtomicLong vs LongAdder
      • 选型速查
    • 七、底层原理简述
    • 八、注意事项

Java 原子类详解

所有类位于 java.util.concurrent.atomic 包下。


一、基本类型原子类

类名 说明
AtomicInteger 原子 int
AtomicLong 原子 long
AtomicBoolean 原子 boolean
AtomicInteger counter = new AtomicInteger(0);counter.incrementAndGet();      // ++i
counter.getAndIncrement();      // i++
counter.decrementAndGet();      // --i
counter.getAndDecrement();      // i--
counter.addAndGet(5);           // += 5
counter.getAndAdd(5);           // 返回旧值,再 += 5
counter.compareAndSet(0, 10);   // CAS:期望0则设为10,返回是否成功
counter.getAndUpdate(x -> x * 2);   // 原子计算,返回旧值
counter.updateAndGet(x -> x * 2);   // 原子计算,返回新值

二、数组原子类

类名 说明
AtomicIntegerArray 原子 int 数组
AtomicLongArray 原子 long 数组
AtomicReferenceArray<V> 原子引用数组
AtomicIntegerArray array = new AtomicIntegerArray(10);
array.incrementAndGet(0);                 // 索引0位置原子+1
array.compareAndSet(0, 1, 5);            // 索引0期望1则设为5

三、引用原子类

类名 说明
AtomicReference<V> 原子引用
AtomicStampedReference<V> 带版本号,解决 ABA 问题
AtomicMarkableReference<V> 带布尔标记
// AtomicReference — 最常见,CAS 更新对象
AtomicReference<User> ref = new AtomicReference<>(new User("张三"));
ref.compareAndSet(oldUser, newUser);           // CAS 更新对象引用
ref.updateAndGet(u -> new User(u.getName() + "_new"));// AtomicStampedReference — 解决 ABA 问题
// 场景:线程A读到值X,线程B把X改成Y又改回X,线程A CAS 时发现还是 X 就更新了,但中间已经变过
AtomicStampedReference<Integer> ref2 = new AtomicStampedReference<>(100, 0);
int stamp = ref2.getStamp();
ref2.compareAndSet(100, 200, stamp, stamp + 1);  // 版本号也参与 CAS// AtomicMarkableReference — 带布尔标记(如"是否已删除")
AtomicMarkableReference<Node> ref3 = new AtomicMarkableReference<>(node, false);
ref3.compareAndSet(oldNode, newNode, false, true); // 标记为 true

ABA 问题图示

线程A:读到值 X ──────────────────── CAS(X → Z) 成功,但不知道中间变过
线程B:        X → Y → XAtomicStampedReference 通过版本号解决:
线程A:读到 (X, stamp=1) ────────── CAS 失败,因为 stamp 已变成 3
线程B:        (X,1) → (Y,2) → (X,3)

四、字段更新器

原子更新某个类的 volatile 字段,适用于大量对象实例的场景,节省内存。

类名 说明
AtomicIntegerFieldUpdater<T> 更新对象 int 字段
AtomicLongFieldUpdater<T> 更新对象 long 字段
AtomicReferenceFieldUpdater<T,V> 更新对象引用字段
class Player {volatile int score;       // 必须是 volatile 且非 private(或通过反射可访问)volatile long timestamp;
}// 创建更新器
AtomicIntegerFieldUpdater<Player> updater =AtomicIntegerFieldUpdater.newUpdater(Player.class, "score");Player p = new Player();
updater.incrementAndGet(p);   // 原子更新 p.score
updater.compareAndSet(p, 0, 100);

适用场景: 有成千上万个 Player 对象,如果每个都包一个 AtomicInteger,内存开销大。用 FieldUpdater 只需一份 Updater 实例。

限制:

  • 字段必须是 volatile
  • 字段不能是 private(除非调用者能访问)
  • 字段不能是 static

五、累加器(JDK 8+)

高并发写入场景下吞吐量远超 AtomicLong

类名 说明
LongAdder 高并发 long 累加
DoubleAdder 高并发 double 累加
LongAccumulator 自定义累加逻辑
DoubleAccumulator 自定义 double 累加逻辑
// LongAdder — 高并发计数首选(如 QPS 统计、请求量计数)
LongAdder adder = new LongAdder();
adder.increment();      // +1
adder.add(10);          // +10
adder.decrement();      // -1
long sum = adder.sum(); // 求和(注意:非强一致性快照,高并发下可能有偏差)
adder.reset();          // 重置为0
adder.sumThenReset();   // 求和并重置// LongAccumulator — 自定义运算(不限于加法)
// 参数:(运算函数, 初始值)
LongAccumulator maxAcc = new LongAccumulator(Long::max, Long.MIN_VALUE);
maxAcc.accumulate(100);
maxAcc.accumulate(200);
maxAcc.get();           // 200LongAccumulator minAcc = new LongAccumulator(Long::min, Long.MAX_VALUE);
minAcc.accumulate(5);
minAcc.accumulate(3);
minAcc.get();           // 3// 也可以做乘法累乘
LongAccumulator product = new LongAccumulator((a, b) -> a * b, 1);
product.accumulate(2);
product.accumulate(3);
product.accumulate(4);
product.get();          // 24

六、核心对比

AtomicLong vs LongAdder

维度 AtomicLong LongAdder
实现原理 CAS 自旋,单热点值 分段累加(Cell 数组),分散竞争
低并发 性能相当 性能相当
高并发 CAS 失败频繁,CPU 自旋浪费 吞吐量远超 AtomicLong
内存占用 8 字节 更多(Cell 数组 + 填充)
瞬时值准确性 精确 近似(sum 时合并 Cell)
适用场景 低并发、需要精确瞬时值、CAS 状态控制 高并发统计计数(QPS、请求量)

选型速查

场景 推荐
高并发计数/统计 LongAdder
需要精确瞬时值 AtomicLong
需要 CAS 精确控制状态(标志位、状态机) AtomicInteger / AtomicLong
CAS 更新对象引用 AtomicReference
需要解决 ABA 问题 AtomicStampedReference
大量对象实例,节省内存 AtomicIntegerFieldUpdater / AtomicLongFieldUpdater
自定义累加逻辑(max/min/乘积等) LongAccumulator

七、底层原理简述

所有原子类的核心是 CAS(Compare And Swap)

CAS(内存地址, 期望值, 新值):如果 内存值 == 期望值 → 更新为新值,返回 true否则 → 不更新,返回 false
  • CAS 是 CPU 级别的原子指令(cmpxchg
  • JDK 通过 Unsafe.compareAndSwapXxxVarHandle 调用
  • CAS 失败时通常自旋重试(自旋锁思想)
  • LongAdder 进一步优化:热点分散到多个 Cell,减少 CAS 竞争

八、注意事项

  1. LongAdder.sum() 不是强一致性的,高并发写入时读到的可能是近似值
  2. AtomicStampedReference 的 stamp 是 int,会溢出回绕,但概率极低
  3. FieldUpdater 的字段必须是 volatile,否则无法保证可见性
  4. 原子类只保证单个操作的原子性,多个原子操作组合不原子:
    // ❌ 这不是原子的
    if (counter.get() < 10) {counter.incrementAndGet();  // 检查和操作之间有间隙
    }
    // ✅ 应该用 compareAndSet
    
  5. JDK 9+ 底层改为 VarHandle,性能和灵活性更好,但 API 不变
http://www.jsqmd.com/news/1169074/

相关文章:

  • 2026汕头黄金回收正规门店推荐:光谱无损检测不上当,8家实体店地址电话全公开 - 不晚生活号
  • 宝珀中国官方售后服务中心|地址与官方电话权威信息声明(2026年7月更新) - 宝珀官方售后服务中心
  • 2026年7月最新常州雷达官方售后联系电话与客户服务中心网点地址 - 亨得利钟表维修中心
  • 五一广场周边钻戒回收,支持上门鉴定当场秒结全款 - 讯息早知道
  • 北京钻戒回收当场转账,4C 无损检测不磨损钻石腰码 - 生活时报
  • 告别音乐平台切换烦恼:Listen1浏览器插件一站式聚合七大平台
  • Windows 11优化神器:5分钟让你的电脑告别臃肿,重获新生
  • IMS V6 MES+AI PCB行业套件:数智融合的制造执行系统实战指南
  • PilotGo-plugin-logs Web界面使用手册:实时日志流监控与查询技巧
  • 通用 AI 写工业品文案空洞,工厂该用什么 AI 文案工具? - 制造业避坑李哥
  • COSE中央电教馆阅读推广人报考条件及全年报名时段汇总 - 实时教育培训动态
  • PvZWidescreen:植物大战僵尸终极宽屏模组完整指南
  • C++项目文件体系全解析:从源码到可执行文件的工程蓝图
  • 如何快速优化Windows系统:终极清理指南
  • 2026年7月最新青岛美度官方售后热线及客户服务网点地址 - 亨得利钟表维修中心
  • Redis 7.x 缓存与锁实战:基于外卖项目应对10个高频面试题的解决方案
  • Midjourney商业接单避坑手册(含客户沟通话术+交付标准SOP+平台审核红线清单),错过再等半年更新
  • 亲身到店探访北京天梭官方售后服务中心|全新维修地址和客服热线(2026年7月最新) - 天梭服务中心
  • 武汉潮气导致金饰发黑折价该怎么算?正规回收区分自然损耗定损 - 讯息早知道
  • Battery Toolkit实用指南:10个高效解决Apple Silicon Mac电池管理问题的方法
  • 猫抓浏览器扩展:简单高效的网页媒体资源捕获工具
  • Mac Mouse Fix:让普通鼠标在macOS上超越专业体验的完全指南
  • 2026深圳翡翠线上估价回收攻略:图文视频远程鉴价、无接触变现,正规平台实测排行 - 全国二奢机构参考
  • Claude Fable 5代码生成技术解析:从原理到工程实践
  • 2026年7月最新郑州真力时官方售后客户服务热线与维修网点地址汇总 - 亨得利官方服务中心
  • Mousecape:终极macOS光标自定义工具完全指南
  • 2026年7月知名的elisa试剂盒企业口碑推荐,试剂盒elisa/羊试剂盒/人试剂盒,elisa试剂盒公司推荐分析 - 品牌推荐师
  • Hermes Agent实战指南:从Harness Engineering约束工程到生产部署
  • 走访长沙多家收表店,综合对比优选卡地亚变现门店 - 讯息早知道
  • 天台县黄金回收被骗,坑人套路揭露,高价黄金回收骗局注意事项 - abc9966abc