https://juejin.cn/post/7325069743143157801

在多线程环境中确保单例模式的线程安全,关键是要控制实例的初始化过程,只允许一个线程创建单例对象,同时确保所有线程访问的同一个实例。以下是几种常见的实现线程安全的单例模式方法:

1. 同步方法(懒汉式实现)

getInstance()方法上添加synchronized关键字,可以防止多个线程同时执行这个方法。每个线程在进入这个方法之前,都必须等待其他线程离开该方法,这保证了只有一个线程可以创建实例。

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

缺点:每次调用getInstance()方法时都进行同步,这可能导致不必要的同步开销,降低了性能。

2. 双重检查锁定(Double-Checked Locking,DCL)

双重检查锁定模式在getInstance()加锁的基础上增加了一个如果实例已创建就不需要再加锁的逻辑。这减少了加锁的次数,提高了性能,同时也保证了线程安全。

public class Singleton {
    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关键字是必须的,它确保了instance变量的写操作之前的所有操作都不会被编译器优化掉,并且其他线程能够看到它的值。

3. 静态内部类(懒汉式的一种)

静态内部类方式是懒汉式单例的一种改进方式,它利用了类加载机制保证了单例只会被创建一次,并且只有在真正使用的时候才创建。