getandupdate基于当前值计算新值,使用unaryoperator;getandaccumulate用二元运算合并当前值与显式传入的update值,使用binaryoperator,适用于累积或归并场景。

getAndAccumulate 和 getAndUpdate 都是 AtomicReference 提供的原子更新方法,但语义和适用场景不同,Lambda 写法也体现这种差异。
getAndUpdate:基于当前值计算新值
它接收一个 UnaryOperator<t></t>(即 T → T),用当前值作为输入,返回要更新的新值。操作是“读-算-写”,整个过程原子执行。
- 参数类型是
UnaryOperator<t></t>,只有一个参数(当前引用对象) - 适合需要根据旧值做简单变换的场景,比如修改对象某个字段、包装新实例等
- 注意:Lambda 里不能依赖外部可变状态,否则破坏原子性
示例:
AtomicReference<stringbuilder> ref = new AtomicReference(new StringBuilder("start"));
ref.getAndUpdate(sb -> new StringBuilder(sb.toString() + "-updated"));
// 返回旧值 StringBuilder("start"),内部引用更新为新 StringBuilder
</stringbuilder>
getAndAccumulate:用二元运算合并新旧值
它接收一个 BinaryOperator<t></t>(即 (T, T) → T),把当前值和你提供的“更新值”一起传入,由你定义合并逻辑。名字里的 “accumulate” 强调“累积”或“归并”语义。
- 第一个参数是当前值,第二个参数是你传入的 update value(不是 Lambda 参数!)
- Lambda 本身不产生 update value;你需要额外提供一个
update参数 - 适合类似“取旧值,与某固定值按规则合并”的场景,比如字符串拼接、数值累加(需配合包装类)、集合合并等
示例:
AtomicReference<string> ref = new AtomicReference("hello");
String old = ref.getAndAccumulate(" world", (prev, next) -> prev + next);
// old == "hello",ref 当前值变为 "hello world"
</string>
关键区别:Lambda 的签名和调用上下文
别混淆两者参数来源:
-
getAndUpdate(op):Lambda 只接收当前值,无其他输入 -
getAndAccumulate(update, accumulator):Lambda 接收两个参数(当前值、你给的 update 值),且update是显式传入的实参 - 二者都保证“读+计算+写”三步不可分割,但
getAndAccumulate更强调“用固定 update 值参与运算”
实际选型建议
想更新为“旧值加工后结果” → 用 getAndUpdate;
想更新为“旧值与某个确定新值按规则合并” → 用 getAndAccumulate。
例如:维护一个线程安全的配置快照,每次用新配置与旧配置 merge → getAndAccumulate(newConf, Config::merge);
每次把对象标记为已处理,生成新状态 → getAndUpdate(obj -> obj.withProcessed(true))。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











