设计模式 - 单例模式

2019-06-17  本文已影响0人  柳经年

0x01 懒汉式

public class LazySingleton {

    private static LazySingleton instance;

    // 私有构造方法,防止外部创建对象
    private LazySingleton() {
    }

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

0x02 饿汉式

public class EagerSingleton {

    private static final EagerSingleton instance = new EagerSingleton();

    public static EagerSingleton getInstance() {
        return instance;
    }
}

0x03 双重检查锁

public class DoubleCheckSingleton {

    private static volatile DoubleCheckSingleton instance;

    // 私有构造方法,防止外部创建对象
    private DoubleCheckSingleton() {
    }

    public static DoubleCheckSingleton getInstance() {
        if (instance == null) {// 步骤1
            synchronized (DoubleCheckSingleton.class) {// 步骤2
                if (instance == null) {// 步骤3
                    instance = new DoubleCheckSingleton();// 步骤4
                }
            }
        }
        return instance;
    }
}

综合了经典的饿汉式和懒汉式的优点,但是有几点需要注意:

0x04 静态内部类

public class StaticHolderSingleton {

    // 私有构造方法,防止外部创建对象
    private StaticHolderSingleton() {
    }

    private static class Holder {
        private static final StaticHolderSingleton INSTANCE = new StaticHolderSingleton();
    }

    public static StaticHolderSingleton getInstance() {
        return Holder.INSTANCE;
    }
}

StaticHolderSingleton 类加载时,静态内部类 Holder 没有被加载进内存。只有当调用 getInstance() 方法从而触发 Holder.INSTANCEHolder 才会被加载,此时初始化 INSTANCE 实例,并且 JVM 能确保 INSTANCE 只被实例化一次。这种方式不仅具有延迟初始化的好处,而且由 JVM 提供了对线程安全的支持。

0x05 枚举

该实现在多次序列化再进行反序列化之后,不会得到多个实例
该实现是由 JVM 保证只会实例化一次,因此不会出现上述的反射攻击

上一篇 下一篇

猜你喜欢

热点阅读