MST

星途 面试题库

面试题:Java单例模式之双重检查锁实现

请用Java代码实现双重检查锁(DCL)的单例模式,并解释volatile关键字在其中的作用。
14.4万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

Java代码实现双重检查锁(DCL)的单例模式

public class Singleton {
    // 使用volatile关键字修饰单例实例
    private static volatile Singleton instance;

    private Singleton() {
        // 私有构造函数,防止外部实例化
    }

    public static Singleton getInstance() {
        // 第一次检查,避免不必要的同步
        if (instance == null) {
            synchronized (Singleton.class) {
                // 第二次检查,确保在同步块内只有一个实例被创建
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

volatile关键字的作用

  1. 防止指令重排:在instance = new Singleton()这行代码中,实际上会有多个步骤,包括分配内存空间、初始化对象以及将对象引用赋值给instance。如果没有volatile关键字,编译器和处理器可能会对这些步骤进行重排,例如先将对象引用赋值给instance(此时对象还未初始化完成),然后再初始化对象。当另一个线程通过第一次if (instance == null)检查时,就可能拿到一个未初始化完全的对象。volatile关键字可以禁止这种指令重排,保证在将instance赋值之前,对象已经初始化完成。
  2. 保证可见性:当一个线程修改了instance的值时,volatile关键字能确保其他线程能够立即看到这个修改。如果没有volatile,其他线程可能无法及时感知到instance的变化,从而导致多次创建实例,破坏单例模式。