美文网首页
单例模式

单例模式

作者: 幸运星32 | 来源:发表于2018-11-28 17:28 被阅读0次
    1:饿汉模式
    public class Singleton{
        private static Singleton instance = new Singleton();
        private Singleton(){
        }
        public static Singleton getInstance(){
              return instance;
        }
    }
    

    这种方式在类加载时就完成了初始化,所以类加载会慢一些,但是获取对象的速度块,它是基于类加载机制,避免类多线程的同步问题,但是没有达到懒加载的效果,如果一直没有使用该类,会造成内存浪费。之所以叫做饿汉,是因为它获取对象的速度像饿汉吃饭的速度一样快。

    2:懒汉模式(线程不安全)
    public class Singleton{
          private static Singleton instance;
          private Singleton(){
          }
          public static Singleton getInstance(){
             if(instance == null){
                instance = new Singleton();
          }
          return instance;
          }
    }
    

    懒汉模式声明了一个静态对象,在用户第一次调用的时候初始化,节约了资源,但是第一次加载时需要实例化,反应较慢,而且在多线程时不能正常工作,他是线程不安全的模式。之所以叫他懒汉是因为他只有在使用的时候才初始化。

    3:懒汉模式(线程安全的)
    public class Singleton{
        private static Singleton instance;
        private Singleton(){
        }
        public static synchronized Singleton getInstance(){
            if(instance == null){
                instance = new Singleton();
            }
        return instance;
        }
    }
    

    这种写法能够在多线程中很好的工作,但是每次调用getInstance方法时都要进行同步,会造成不必要的同步开销,而且大部分时候我们用不到同步,所以不建议用此模式。

    4:双重检查模式(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();
                  }
              }
          }
      }
    }
    

    这种写法其实是对线程安全的懒汉模式的一种优化,在getinstance方法中对instance进行了两次空判断,第一次是为了不必要的同步,第二次是在instance为空的情况下才创建实例。这里的volatile关键字,是为了满足变量变化时,实时的体现在共享内存中,放在这里可能会影响一些性能,但考虑到程序的正确性,牺牲这点性能是值得的。DCL的优点是资源利用率搞,第一次执行getinstance的时候才实例化对象,效率高。但是在高并发的情况下会出现失效的问题。

    5:静态内部类单例模式
    public class Singleton{
      private Singleton(){
    
      }
      public static Singleton getInstance(){
        return SingletonHolder.sInstance;
      }
    
      private static class SingletonHolder{
        private static final Singleton sInstance = new Singleton();
      }
    }
    

    这种形式在第一次加载Singleton类的时候并不会初始化sInstance,只有在第一次调用getInstance方法时虚拟机加载SingleHolder并初始化sInstance。这样不仅能确保线程安全,也能保证Singleton类的唯一性。所以静态内部类单例模式是比较推荐的模式。

    6:枚举单例
    public enum Singleton{
      INSTANCE;
      public void doSomeThing(){
    
      }
    }
    

    枚举单例是线程安全的,并且在任何情况下都是单例。但是在Android开发中枚举是不推荐使用的。

    相关文章

      网友评论

          本文标题:单例模式

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