单例模式

    xiaoxiao2021-03-25  56

    单例模式是在学习Java设计模式过程中接触最多的一个模式。单例模式的写法有好几种形式,虽然形式各异,但目的都是为了保证 一个类仅有一个实例,并提供一个访问它的全局入口(getInstance())。

    饿汉式

    public class Singleton { private static Singleton instance = new Singleton(); //构造函数私有化 ,确保外部无法直接实例化 private Singleton() {}; public Singleton getInstance() { return instance; } }

    懒汉式(添加了“双检锁”,解决数据同步问题)

    public class Singleton { private static Singleton instance; private Singleton() {}; //添加“双检锁”。解决数据同步问题 public Singleton getInstance() { if(instance == null) { synchronized (Singleton.class) {//synchoronized关键字也是可以加到方法上,但是这样效率太低了 if(instance == null) { instance = new Singleton(); } } } return instance; } }

    静态内部类中创建单例类实例

    //简单实现 public class Singleton { private Singleton() {}; private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public Singleton getInstance() { return SingleHolder.INSTANCE; } }

    上面这种实现单例的方式,同样无法避免通过Java的反射机制调用私有的构造函数创建出第二个单例类的实例。为了避免这个问题,我们可以去修改构造函数,使它在被要求创建第二个实例时抛出异常。

    //避免“反射”机制攻击 public class Singleton { private static boolean isCreated; // 如果二次调用构造函数就抛出一个异常 private Singleton() { synchronized(Singleton.class) { if(isCreated) { throw new RuntimeException("单例模式被攻击了!"); }else { isCreated = true; } } } private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public Singleton getInstance() { return SingletonHolder.INSTANCE; } }

    枚举实现单例

    public enum Singleton { INSTANCE; }

    单元素的枚举类型是目前实现单例模式的最佳实践,即可以防止反射攻击,可以防止序列化破坏单例模式。

    参考文章 如何防止单例模式被 JAVA 反射攻击 singleton模式四种线程安全的实现

    转载请注明原文地址: https://ju.6miu.com/read-39641.html

    最新回复(0)