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 底层使用了内存屏障机制来避免指令重排序。

相关推荐
Meepo_haha几秒前
python爬虫——爬取全年天气数据并做可视化分析
java
xiaohe071 分钟前
JAVA系统中Spring Boot 应用程序的配置文件:application.yml
java·开发语言·spring boot
羊小蜜.1 分钟前
C++17: map & multimap—— 键值映射容器
开发语言·c++·stl
Eternity_GQM2 分钟前
【CMake入门】
java·开发语言
糖猫猫cc6 分钟前
Kite 实现逻辑删除
java·kotlin·orm·kite
Memory_荒年7 分钟前
Dubbo调优实战:从QPS 1000到10000的惊险过山车之旅
java·后端·dubbo
Cosolar9 分钟前
别再羡慕 Python 了!Java 开发者的 AI Agent 全指南:四大框架从选型到实战
java·人工智能·后端
色空大师19 分钟前
网站搭建实操(三)后台管理-2-forum-core)
java·redis·网站·搭建网站
Memory_荒年21 分钟前
Dubbo高级实战:从“能用”到“好用”的奇技淫巧
java·后端