[java回顾]双重校验锁实现对象单例

127 阅读1分钟
public class Singleton {

    private volatile static Singleton singleton;

    private Singleton() {
    }

    public static Singleton getUniqueInstance() {
        if (singleton == null) {

            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

这里的单例对象用volatile关键字修饰的原因是防止指令重排序,防止使用未初始化的单例对象

原因是 singleton = new Singleton()实际上是分三步执行的

  1. singleton分配内存空间
  2. 初始化singleton
  3. singleton指向分配的内存地址

所以在多线程环境下,当执行顺序是1 3 2时,就可能出现获取到未初始化对象的情况