设计模式之单例模式

单例模式

我们在单例类中添加一个该类的成员属性Instance,并提供一个getInstance方法访问它。一般来说,有如下几种实现。

  1. 饿汉式

    这里的单例,是由JVM加载类时初始化生成的单例,由JVM保证了线程安全。但是耗资源,起步慢。

    public class HungrySingleton {
    
        private static HungrySingleton instance = new HungrySingleton();
    
        public static HungrySingleton getInstance(){
            return instance;
         }
      
        private HungrySingleton(){}
    }
    
  2. 懒汉式

    不是在类加载时生成,所以需要我们自己通过同步保证线程安全。通常用双重校验锁实现,是写法最复杂的方式。

    public class DoubleLockSingleton {
        private static volatile DoubleLockSingleton instance;
    
        public static DoubleLockSingleton getInstance() {
            if(instance == null){
                synchronized (DoubleLockSingleton.class) {
                    if(instance == null) {
                        instance = new DoubleLockSingleton();
                    }
                }
            }
            return instance;
        }
      
        private DoubleLockSingleton() { }
    }
    
  3. 静态内部类实现

    也是懒汉式的,写法很简洁,个人觉得是最推荐的写法。同时它也是线程安全的,因为单例是在嵌套类被加载时生成的。

    public class StaticInnerSingleton {
    
        private static class Holder{
            private static StaticInnerSingleton instance = new StaticInnerSingleton();
        }
    
        public static StaticInnerSingleton getInstance(){
            return Holder.instance;  // 执行到这时才会加载Holder嵌套类。
        }
    
        private StaticInnerSingleton(){ }
    }
    
  4. 枚举类

    枚举自身的特性,JVM会保证线程安全和单一实例。它也是饿汉式的,枚举类加载时就会创建单例。枚举最大的优点在于可以预防反射导致的多例,因为反射无法作用于枚举类。

    public enum EnumSingleton {
    
        INSTANCE;
        // 枚举类的构造函数默认是private的
        EnumSingleton(){}
      
        public void doSomething() {
            // 这个类的其他方法
        }
    }
    
    // 使用时直接 EnumSingleton.INSTANCE 就获取到了该类的单例。
    

设计模式之单例模式

上一篇:批量给文件名增加或删除指定字段


下一篇:【652】LaTeX 表格内部换行