DCL 单例模式设计为什么需要 volatile 修饰实例对象

DCL 问题,是在基于双重检查锁设计下的单例模式中,存在不 完整对象的问题。而这个不完整对象的本质,是因为指令重排序导致的。

java 复制代码
public class DCLExample {
    private static DCLExample instance;
    public static DCLExample getInstance(){
        if (instance==null){
            synchronized (DCLExample.class){
                if (instance==null){
                    instance = new DCLExample();
                }
            }
        }
        return instance;
    }
}

当我们使用 instance=new DCLExample()构建一个实例对象的时候,因为 new 这个操作并不是原子的。所以这段代码最终会被编译成 3 条指令:

  • 为对象分配内存空间
  • 初始化对象
  • 把实例对象赋值给 instance 引用

由于这是三个指令并不是原子的(如图)。 按照重排序规则,在不影响单线程执行结果的情况下,两个不存在依赖关系的指令允许重排序,也就是不一定会按照代码编写顺序来执行。

这样一来,(如图)就会导致其他线程可能拿到一个不完整的对象,也就是这个 instance已经分配了引用实例,但是这个实例的初始化指令还没执行。


解决办法就是可以在 instance 这个变量上增加一个 volatile 关键字修饰,volatile 底层使用了内存屏障机制来避免指令重排序。

相关推荐
Coder码匠21 分钟前
Dockerfile 优化实践:从 400MB 到 80MB
java·spring boot
Fcy6481 小时前
C++ set&&map的模拟实现
开发语言·c++·stl
你怎么知道我是队长8 小时前
C语言---枚举变量
c语言·开发语言
李慕婉学姐8 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
吃茄子的猫8 小时前
quecpython中&的具体含义和使用场景
开发语言·python
云栖梦泽8 小时前
易语言中小微企业Windows桌面端IoT监控与控制
开发语言
数据大魔方8 小时前
【期货量化实战】日内动量策略:顺势而为的短线交易法(Python源码)
开发语言·数据库·python·mysql·算法·github·程序员创富
奋进的芋圆9 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin10 小时前
设计模式之桥接模式
java·设计模式·桥接模式
Edward.W10 小时前
Python uv:新一代Python包管理工具,彻底改变开发体验
开发语言·python·uv