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

是否需将Supplier类成员声明为volatile以保障线程安全?

问题解答:懒加载场景下heavy成员是否需要声明为volatile

结论:是的,必须将heavy成员声明为volatile,具体原因如下:

  • 可见性无法保证
    当线程在synchronized方法createAndCacheHeavy()中修改heavy的引用(从方法引用替换为HeavyFactory实例)时,如果heavy未标记为volatile,其他线程在非同步的getHeavy()方法中读取heavy时,可能无法感知到这个最新的引用变化。这会导致其他线程反复触发createAndCacheHeavy(),甚至多次创建Heavy实例,完全违背懒加载单例的设计目的。

  • happens-before关系缺失
    createAndCacheHeavy()作为同步方法,仅能保证锁释放前的写操作对后续获取同一锁的线程可见,但对未获取锁的getHeavy()调用线程不提供可见性保障。非同步的getHeavy()读取heavy时没有触发内存屏障,无法确保读到的是最新的heavy引用。

  • 变种DCL模式的要求
    这段代码本质是变种的双重检查锁定(DCL)模式:第一次读取heavy是非同步的,进入同步方法后再次检查heavy状态。在DCL模式中,懒加载变量必须声明为volatile,否则会出现指令重排序或可见性问题,这里的heavy变量也遵循相同规则。

修正后的heavy声明应为:

private volatile Supplier<Heavy> heavy = this::createAndCacheHeavy;

修改后,heavy的写操作(同步方法内)会对所有后续读操作(getHeavy()内)建立happens-before关系,确保所有线程都能看到最新的heavy引用,避免重复创建对象或读取无效的Supplier实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 13:27:15