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

Java线程安全单更新方案咨询:AtomicReference适用性及示例需求

多线程下单次对象更新实现方案

基于AtomicReference的实现

使用AtomicReference的updateAndGet方法可完美满足需求——该方法通过CAS(Compare-And-Swap)机制保证原子性,确保只有一个线程能执行对象更新逻辑,其他线程直接复用更新后的实例。

代码示例

import java.util.concurrent.atomic.AtomicReference;

// 模拟业务服务类
class Service {
    // 故障检测逻辑,根据实际场景实现
    public boolean isFaulty() {
        // 示例:检查连接是否断开、服务是否超时等
        return false;
    }

    // 创建新服务实例的方法,实际包含初始化资源、连接等逻辑
    public static Service createNewService() {
        return new Service();
    }
}

// 共享对象持有类
public class SharedServiceHolder {
    private final AtomicReference<Service> serviceRef = new AtomicReference<>(Service.createNewService());

    public Service getService() {
        Service current = serviceRef.get();
        // 检查当前实例是否故障
        if (current.isFaulty()) {
            // 原子性更新:仅当当前引用未被其他线程修改时执行更新
            Service updated = serviceRef.updateAndGet(s -> {
                // 二次检查,避免其他线程已完成更新
                if (s.isFaulty()) {
                    return Service.createNewService();
                }
                return s;
            });
            return updated;
        }
        return current;
    }
}

关键说明

  • updateAndGet内部通过循环CAS实现,多个线程同时触发更新时,只有第一个成功CAS的线程会执行createNewService,其他线程直接获取已更新的实例。
  • 内部二次检查是必要的:避免当前线程获取current后,其他线程已完成更新,此时无需重复创建实例。

基于Guava的实现

如果项目已依赖Guava,可使用LoadingCache实现,它内置原子加载逻辑,确保同一时间只有一个线程执行实例创建操作。

代码示例

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

import java.util.concurrent.ExecutionException;

class Service {
    public boolean isFaulty() {
        return false;
    }

    public static Service createNewService() {
        return new Service();
    }
}

public class GuavaSharedServiceHolder {
    // 单实例缓存,使用固定key标识唯一实例
    private final LoadingCache<String, Service> serviceCache = CacheBuilder.newBuilder()
            .build(new CacheLoader<String, Service>() {
                @Override
                public Service load(String key) {
                    return Service.createNewService();
                }
            });

    public Service getService() throws ExecutionException {
        Service current = serviceCache.get("SINGLETON_SERVICE");
        if (current.isFaulty()) {
            // 失效旧实例,触发重新加载
            serviceCache.invalidate("SINGLETON_SERVICE");
            // 重新获取新实例,LoadingCache保证原子加载
            return serviceCache.get("SINGLETON_SERVICE");
        }
        return current;
    }
}

关键说明

  • LoadingCache的get方法保证:当多个线程同时请求未缓存的key时,只有一个线程会执行load方法创建实例,其他线程阻塞等待加载完成。
  • 调用invalidate后,下一次get会触发新的加载,确保故障后仅创建一次新实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 18:33:10