MST

星途 面试题库

面试题:Java中如何确保线程安全的单例模式

请用Java代码实现一个线程安全的单例模式,并解释其中使用到的确保线程安全的机制。
26.1万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

实现代码

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;
    }
}

线程安全机制解释

  1. volatile关键字:对instance变量使用volatile关键字,保证了该变量的可见性。当一个线程修改了instance的值,其他线程能够立即看到这个修改。同时,volatile还禁止了指令重排优化,确保在instance = new Singleton()这条语句中,不会出现先分配内存空间,然后再初始化对象的情况,避免其他线程在对象未完全初始化时就获取到instance
  2. 双重检查锁定(Double-Checked Locking):在getInstance方法中,首先检查instance是否为null,如果不为null,则直接返回instance,避免了不必要的同步开销。当instancenull时,进入synchronized块,再次检查instance是否为null,这是因为可能有多个线程同时通过了第一次null检查,只有一个线程能够进入synchronized块并创建实例,后续线程再次检查时,instance已经不为null,直接返回已创建的实例,从而确保了线程安全。
  3. 私有构造函数:将构造函数声明为private,防止外部通过构造函数创建新的实例,保证了单例模式中只有一个实例存在。