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

如何在Spring组件中实现线程安全的字段懒加载?

原方案无效,存在多处问题及修改方案

原代码的核心问题

  • 语法错误:getInstance()方法返回值类型缺少闭合尖括号;initMap()方法未声明返回类型;map = map.put(...)逻辑错误,put方法返回对应key的旧值(首次调用为null),会导致map被赋值为null。
  • 初始化逻辑无法触发:getMap()直接返回未初始化的map,负责初始化的getInstance()是私有方法且未被调用,导致map永远为null。
  • 线程不安全:即使修复调用逻辑,多线程场景下可能多次执行initMap(),造成重复初始化。
  • static字段设计冗余:Example本身是Spring单例Bean,使用static字段完全没必要,还会导致实例依赖的service与类级字段耦合,不符合Spring实例管理逻辑。

修改后的代码

@Component
public class Example {
    
    @Autowired
    private TestService service;
    
    private Map<String, TestObject> map;

    public Map<String, TestObject> getMap() {
        return getInstance();
    }
    
    private Map<String, TestObject> getInstance() {
        // 双重检查锁实现线程安全的懒加载
        if (map == null) {
            synchronized (this) {
                if (map == null) {
                    initMap();
                }
            }
        }
        return map;
    }
    
    private void initMap() {
        map = new HashMap<>();
        map.put("example", service.someMethod());
    }
}

关键修改点说明

  • 移除map的static修饰符:借助Spring单例Bean的特性,保证map在应用生命周期内唯一。
  • 修复语法错误:补全方法返回类型、修正put方法的赋值逻辑。
  • 让getMap()调用getInstance():触发懒加载逻辑,仅在第一次调用getMap()时初始化map。
  • 增加双重检查锁:解决多线程环境下的重复初始化问题,保证线程安全。
  • 修正initMap()逻辑:先创建HashMap实例,再调用put添加元素,避免map被赋值为null。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:37:35