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

介绍java中atomic及相关类

文章目录

      • 一、Atomic 类的核心原理
      • 二、常见 Atomic 类及用法
        • 1. 基本类型原子类
          • (1)`AtomicInteger`(原子更新 int)
          • (2)`AtomicLong`(原子更新 long)
          • (3)`AtomicBoolean`(原子更新 boolean)
        • 2. 引用类型原子类
          • (1)`AtomicReference<V>`(原子更新对象引用)
          • (2)`AtomicStampedReference<V>`(解决 ABA 问题)
          • (3)`AtomicMarkableReference<V>`(标记是否修改)
        • 3. 数组类型原子类
          • (1)`AtomicIntegerArray`(原子更新 int 数组)
          • (2)`AtomicLongArray` 和 `AtomicReferenceArray`
        • 4. 字段更新器(FieldUpdaters)
          • (1)`AtomicIntegerFieldUpdater`(更新对象的 int 字段)
      • 三、Atomic 类的适用场景
      • 四、局限性
      • 总结

Java 中的 java.util.concurrent.atomic 包提供了一组原子操作类,用于实现多线程环境下的无锁线程安全编程。这些类基于硬件提供的CAS(Compare-And-Swap,比较并交换) 指令实现,避免了传统锁机制的性能开销,适用于简单值的并发更新场景(如计数器、标志位等)。

一、Atomic 类的核心原理

Atomic 类的线程安全依赖 CAS 操作,其基本逻辑如下:

  1. 读取当前内存中的值(V)。
  2. 计算目标值(N,基于当前值的更新结果)。
  3. 用 CAS 指令比较内存中的值是否仍为 V
  • 若是,将内存值更新为 N,操作成功。
  • 若否(被其他线程修改),不做操作,重试或放弃(通常会循环重试)。

CAS 是硬件级别的原子操作,无需加锁即可保证操作的原子性,因此性能优于synchronizedReentrantLock

二、常见 Atomic 类及用法

atomic 包提供了针对不同数据类型的原子类,可分为以下几类:

1. 基本类型原子类

用于对 intlong 等基本类型进行原子更新。

(1)AtomicInteger(原子更新 int)

核心方法:

  • getAndIncrement():自增 1,返回更新前的值(类似 i++)。
  • incrementAndGet():自增 1,返回更新后的值(类似 ++i)。
  • getAndAdd(int delta):增加指定值,返回更新前的值。
  • compareAndSet(int expect, int update):若当前值等于 expect,则更新为 update,返回是否成功。

示例:

AtomicInteger count = new AtomicInteger(0);// 自增(线程安全)
count.incrementAndGet(); // 结果为 1// 条件更新
boolean success = count.compareAndSet(1, 100); // 成功,返回 true,值变为 100
(2)AtomicLong(原子更新 long)

用法与 AtomicInteger 类似,用于 long 类型的原子操作。在 32 位 JVM 上,long 的非原子操作可能存在拆分风险,AtomicLong 可保证其原子性。

(3)AtomicBoolean(原子更新 boolean)

用于原子更新布尔值,常用 compareAndSet 实现线程安全的开关控制:

AtomicBoolean flag = new AtomicBoolean(false);// 若当前为 false,则更新为 true
if (flag.compareAndSet(false, true)) {System.out.println("执行初始化操作");
}
2. 引用类型原子类

用于原子更新对象引用,支持更复杂的并发场景。

(1)AtomicReference<V>(原子更新对象引用)

可对任意对象引用进行原子操作,例如原子更新用户对象:

class User {String name;public User(String name) { this.name = name; }
}AtomicReference<User> userRef = new AtomicReference<>(new User("Alice"));// 原子更新用户(若当前是 Alice,则改为 Bob)
User oldUser = new User("Alice");
User newUser = new User("Bob");
boolean swapped = userRef.compareAndSet(oldUser, newUser); // 成功,返回 true
(2)AtomicStampedReference<V>(解决 ABA 问题)

AtomicReference 存在 ABA 问题(值从 A 变为 B 再变回 A,CAS 会误认为未修改)。AtomicStampedReference 通过版本号(stamp)解决此问题,每次更新时版本号递增:

// 初始化:值为 "A",版本号为 0
AtomicStampedReference<String> ref = new AtomicStampedReference<>("A", 0);int[] stampHolder = new int[1];
String current = ref.get(stampHolder); // current = "A", stampHolder[0] = 0// 只有当值为 "A" 且版本号为 0 时,才更新为 "B",版本号+1
boolean success = ref.compareAndSet("A", "B", 0, 1); // 成功
(3)AtomicMarkableReference<V>(标记是否修改)

AtomicStampedReference 类似,但用布尔值(mark)标记是否被修改,而非版本号,适用于只需判断“是否被修改”的场景。

3. 数组类型原子类

用于原子更新数组中的元素。

(1)AtomicIntegerArray(原子更新 int 数组)
int[] arr = {1, 2, 3};
AtomicIntegerArray atomicArr = new AtomicIntegerArray(arr);// 原子更新索引 1 的元素(加 5)
atomicArr.addAndGet(1, 5); // 数组变为 [1, 7, 3]// 条件更新索引 0 的元素
atomicArr.compareAndSet(0, 1, 10); // 索引 0 的值从 1 变为 10
(2)AtomicLongArrayAtomicReferenceArray

分别用于原子更新 long 数组和对象引用数组,用法与 AtomicIntegerArray 类似。

4. 字段更新器(FieldUpdaters)

用于原子更新对象的非静态字段(需字段可见性为 volatile),无需修改类定义即可实现原子操作。

(1)AtomicIntegerFieldUpdater(更新对象的 int 字段)

示例:

class Student {volatile int score; // 必须是 volatile 修饰的非静态字段public Student(int score) { this.score = score; }
}// 创建更新器(指定类和字段名)
AtomicIntegerFieldUpdater<Student> updater = AtomicIntegerFieldUpdater.newUpdater(Student.class, "score");Student student = new Student(80);
// 原子更新 score 字段(加 10)
updater.addAndGet(student, 10); // score 变为 90

类似的还有 AtomicLongFieldUpdaterAtomicReferenceFieldUpdater,用于更新 long 字段和对象字段。

三、Atomic 类的适用场景

  1. 计数器:如接口调用次数、并发任务数统计(AtomicIntegerAtomicLong)。
  2. 标志位:如线程安全的开关控制(AtomicBoolean)。
  3. 无锁数据结构:如实现非阻塞队列、栈等(基于 AtomicReference)。
  4. 乐观锁场景:通过版本号控制(AtomicStampedReference)实现并发更新。

四、局限性

  1. 仅支持简单操作:适合单一变量的原子更新,复杂逻辑(如多变量联动)仍需锁机制。
  2. 可能导致自旋消耗:CAS 失败时会循环重试,高并发下可能浪费 CPU 资源。
  3. 无法解决所有并发问题:如需要互斥的场景(如“检查-修改-操作”三步原子性),可能仍需锁。

总结

atomic 包提供的原子类通过 CAS 操作实现了高效的线程安全,适合简单值的并发更新场景,性能优于传统锁机制。但需注意其局限性:仅适用于单一变量操作,复杂场景仍需结合锁或其他并发工具。实际开发中,应根据业务复杂度选择合适的并发方案。

http://www.dtcms.com/a/332045.html

相关文章:

  • PERC初探暨小试牛刀
  • Vue3 vxeTree树形组件完全指南:从入门到精通的完整使用教程
  • QT6(可视化UI设计代码实现)
  • MATLAB实现图像增强(直方图均衡化)
  • 数学分析| 极限论| 1.数列极限常用方法总结
  • App冷启动阶段Open Dexfiles实现原理【ART虚拟机系列2】
  • docker nginx 定时脚本保存30天日志信息
  • MFC的使用——使用ChartCtrl绘制曲线
  • 2025.8.13~14 实习总结
  • 计算机网络技术学习-day1《网络乾坤:从比特洪流到协议星河的奇幻之旅》​
  • MCU中的LTDC(LCD-TFT Display Controller)
  • 网卡聚合teamdctl
  • 大模型技术栈全景
  • Java 图片像素碰撞检测
  • Linux软件编程-进程(1)
  • 【嵌入式C语言】四
  • 【PCB设计经验】3D模型在线预览!效率便捷!
  • pycharm远程连接服务器跑实验详细操作
  • ClickHouse 日常运维命令总结
  • 并发编程原理与实战(二十三)StampedLock应用实战与其他锁性能对比分析
  • CentOS7系统负载异常飙高全链路分析详细指南
  • Kaggle赛题分析1:Elo用户忠诚度评分预测(2)-特征工程与模型训练
  • 解决Python环境混乱问题
  • 【159页PPT】智慧方案企业数字化转型流程体系建设与运营方案(附下载方式)
  • 鸿蒙应用开发实战:模块内页面路由与Navigation导航详解
  • 深入理解提示词工程:从入门到精通的AI对话艺术
  • 零基础-动手学深度学习-10.3. 注意力评分函数
  • [vibe coding-lovable]lovable是不是ai界的复制忍者卡卡西?
  • 《零基础入门AI:深度学习中的视觉处理(卷积神经网络(CNN)进阶)》
  • 光猫 SK-D840N 获取管理员密码和登录Telnet简记