You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于当前值的Predicate原子性地条件更新AtomicReference?

基于AtomicReference实现条件性原子更新

我们可以通过自定义扩展AtomicReference的方式,实现你需要的conditionallyUpdate方法,满足基于当前值判断(如空值、过期)的原子更新需求,并发场景下保证操作的原子性,且其他线程在操作执行期间仍能看到原有值。

自定义增强型AtomicReference实现

封装一个EnhancedAtomicReference类,实现目标方法:

import java.util.function.UnaryOperator;
import java.util.concurrent.atomic.AtomicReference;

public class EnhancedAtomicReference<V> extends AtomicReference<V> {

    /**
     * 根据函数结果更新值,仅当函数返回非null时执行更新。
     * 函数的入参为当前引用的实际值。
     * 方法执行期间,并发调用的线程仍会看到当前的原有值。
     *
     * @param function 接收当前值、返回新值的函数;返回null则不执行更新
     * @return 更新后的最终值(可能是原有值,也可能是新值)
     */
    public V conditionallyUpdate(UnaryOperator<V> function) {
        while (true) {
            V current = get();
            V newValue = function.apply(current);
            // 函数返回null,直接返回当前值,不更新
            if (newValue == null) {
                return current;
            }
            // CAS尝试更新,成功则返回新值,失败则重试
            if (compareAndSet(current, newValue)) {
                return newValue;
            }
        }
    }
}

使用示例

按照需求实现获取非过期值的方法:

public class ExampleUsage {
    private final EnhancedAtomicReference<Value> myAtomicRef = new EnhancedAtomicReference<>();

    public Value getNonExpiredValue() {
        return myAtomicRef.conditionallyUpdate(existingVal -> {
            if (existingVal == null || existingVal.isExpired()) {
                return getNewVal();
            }
            return null; // 无需更新,保留原有值
        });
    }

    // 模拟获取新值的方法
    private Value getNewVal() {
        return new Value();
    }

    // 模拟带过期判断的Value类
    static class Value {
        public boolean isExpired() {
            // 此处实现过期判断逻辑
            return false;
        }
    }
}

实现说明

  • 该方法通过CAS循环保证原子性:每次循环获取当前值,计算新值后尝试更新,若更新失败(说明有其他线程修改了值)则重试,直到成功或无需更新。
  • 当函数返回null时,直接返回当前值,跳过更新操作,符合"原有值无需修改时不操作"的需求。
  • 这个逻辑和ConcurrentMap的compute方法类似,但专门针对单个原子引用场景,更轻量化。

内容的提问来源于stack exchange,提问作者peterh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 18:32:34