美文网首页
设计模式-单例模式

设计模式-单例模式

作者: dashingqi | 来源:发表于2020-09-12 16:55 被阅读0次

    单例模式

    保证了一个类只有一个实例,并提供了一个获取它实例的方法

    几种写法

    饿汉模式

    • 代码如下

      public class Singleton {
          private static Singleton instance = new Singleton();
      
          private Singleton() {
          }
      
          public static Singleton getInstance() {
              return instance;
          }
      }
      
      • 该实例 是类的成员之一,在类加载的时候就初始化好了
      • 类的加载比较慢,但是获取类的实例是很快的。
      • 这种基于类加载机制,避免了多线程同步问题。
      • 因为是在类加载的时候就初始化好了,如果从来没有使用过久浪费了内存。
    • 懒汉模式(线程不安全的)

      public class Singleton {
          private static Singleton instance;
      
          private Singleton() {
          }
      
          public static Singleton getInstance() {
              if (instance == null) {
                  instance = new Singleton();
              }
              return instance;
          }
      }
      
      • 第一次加载的时候需要实例化,反应慢些
      • 是线程不安全的,在多线程下不能安全工作。
    • 懒汉模式(线程安全的)

      public class Singleton {
          private static Singleton instance;
      
          private Singleton() {
          }
      
          public static synchronized Singleton getInstance() {
              if (instance == null) {
                  instance = new Singleton();
              }
              return instance;
          }
      }
      
      
      • 保证了多线程下的安全性
      • 每次调用都需要进行同步,造成不必要的同步开销。
    • 双重检查模式(DCL)

      public class Singleton {
          private volatile static Singleton instance;
      
          private Singleton() {
          }
      
          public static  Singleton getInstance() {
              if (instance == null) {
                  synchronized (Singleton.class){
                      if (instance == null){
                          instance = new Singleton();
                      }
                  }
              }
              return instance;
          }
      }
      
      
      • 第一次非空判断,是为了不必要的同步
      • 第二次在为null的情况下创建实例。
      • 建议使用静态内部类单例模式
    • 静态内部类单例模式

      public class Singleton {
      
          private Singleton() {
          }
      
          public static Singleton getInstance() {
              return SingleHolder.mInstance;
          }
      
          private static class SingleHolder {
              private static final Singleton mInstance = new Singleton();
          }
      }
      
      
      • 静态内部类不会随着外部类的加载被立即加载。所以mInstance就不会被初始化,不占用内存。
      • 当第一次调用getInstance方法的时候,虚拟机才会去加载SingleHolder。
      • 当多个线程同时去初始化一个类的,那么有且只有一个线程去执行初始化,其他都将会被阻塞等待,直到初始化结束。
      • 所以就是线程安全的。
      • 静态内部类并不是一个非常完美的,它不能够传递参数,比如我们需要的Context,所以在DCL和它之间根据不同的业务场景,可以选择一下。
    • 枚举单例

      public enum  Singleton {
          INSTANCE;
          public void method(){
              
          }
      }
      
      • 是线程安全的

    总结

    • 单利模式,都会显示的写出构造方法,并使用private关键字修饰,保证力一个应用中只能产生一个实例。
    优点
    • 单利模式在内存中一个实例,那么就不会占用很多的内存。
    • 因为只存在一个实例,可以有效避免减少系统的性能开销,比如一个单利类中有很多读取配置文件啊,和其他类产生依赖,那么我们可以考虑使用单利模式,真样创建一个就永久保留在内存中,不会因为重复创建和销毁而对系统增加压力。
    • 同样,如果一个单利类中有很O操作,比如写文件的动作,一个单利类能保证避免对同一个资源文件的同时写操作,避免对资源的浪费了。
    缺点
    • 单利类不像其他设计模式那样,有接口,有实现类,它没有,这样就导致它的灵活性就不高,扩展性不高
    • 单利类为什么不能用接口呢?
      • 对于单利类来说,我们最终的目的是自行化创建类的实例,对于接口或者抽象类来说本省就不能被实例化,并且这对于创建类实例来说也没有意义。
      • 单利类可以去实现接口或者被继承,可以在业务中自由选择嘛。

    相关文章

      网友评论

          本文标题:设计模式-单例模式

          本文链接:https://www.haomeiwen.com/subject/wliwektx.html