atomicreference 通过传递实例引用实现跨方法线程安全共享,所有操作作用于同一内存地址,基于 cas 保证原子性;需避免重赋值变量、内部对象非线程安全及 get 后非原子修改。

AtomicReference 本身就是一个线程安全的引用容器,它在方法间传递时,共享的是它所包装的对象引用(即 AtomicReference 实例本身),而不是它内部的值副本。只要多个方法操作的是同一个 AtomicReference 实例,就能实现跨方法的状态共享与原子修改。
关键点:传的是 AtomicReference 对象的引用,不是值
Java 中对象参数传递是“按共享引用传递”(pass-by-sharing)。当你把一个 AtomicReference 实例作为参数传给另一个方法时,接收方拿到的是该实例的引用,和调用方指向同一个堆内存地址。因此:
- 所有方法调用
get()都读取同一个最新值 - 所有方法调用
set()、compareAndSet()、updateAndGet()等都会作用于同一份状态 - 无需额外同步,底层基于 CAS(Compare-and-Swap)保证原子性
典型使用方式:作为共享状态载体传入多个方法
例如,用 AtomicReference 保存一个可变配置或计数器,在初始化后传给多个协作方法:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
AtomicReference<string> config = new AtomicReference("default");
processA(config); // 可能 set("prod")
processB(config); // 可能 compareAndSet("prod", "staging")
System.out.println(config.get()); // 输出最终结果,如 "staging"
</string>
只要 processA 和 processB 接收的是同一个 config 变量,它们的操作就天然共享状态。
注意避免的误区
-
不要重新赋值 AtomicReference 变量本身:比如
ref = new AtomicReference(...),这会让后续方法拿到新实例,失去共享性 - 内部对象仍需注意线程安全:AtomicReference 保证引用更新原子性,但不保证其包装的对象(如 ArrayList)内部操作线程安全。若需修改内部对象状态,应确保该对象自身线程安全,或用不可变对象 + 替换整个引用(推荐)
-
慎用 get() 后直接修改内容:比如
ref.get().add(x)(假设是 List),这不是原子操作,且可能被其他线程并发修改。应改用updateAndGet或accumulateAndGet做整体替换
进阶技巧:用 updateAndGet 实现无锁状态转换
适合需要基于当前值计算新值的场景,避免 ABA 问题和竞态条件:
AtomicReference<integer> counter = new AtomicReference(0); // 多个线程/方法可安全调用: counter.updateAndGet(prev -> prev + 1); // 原子自增 counter.updateAndGet(prev -> Math.max(prev, 100)); // 设最小值 </integer>
这种写法天然支持跨方法协作:无论哪个方法调用,都基于最新的值做计算并更新,无需加锁或关心执行顺序。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










