Android 设计模式-单例模式(Singleton Patt

作者: Code猎人 | 来源:发表于2018-04-09 14:23 被阅读75次

    单例模式的几种写法

    1、饿汉模式

    public class Singleton {  
     private static Singleton instance = new Singleton();  
     private Singleton (){
     }
     public static Singleton getInstance() {  
     return instance;  
     }  
     }  
    

    这种写法是在类装载时就实例化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 singleton;  
      private Singleton (){
      }   
      public static Singleton getSingleton() {  
      if (singleton == null) {  
          synchronized (Singleton.class) {  
          if (singleton == null) {  
              singleton = new Singleton();  
          }  
         }  
     }  
     return singleton;  
     }  
    } 
    

    这种写法在getSingleton方法中对singleton进行了两次判空,第一次是为了不必要的同步,第二次是为了在null的情况下创建实例。我们会发现上面代码有一个volatile关键字,因为在这里会有DCL失效问题,原因是Java编译器允许处理器乱序执行。那么为了解决这个问题,在JDK1.5之后,具体化了volatile关键字,只要定义时加上他,可以保证执行的顺序,虽然会影响性能。这种方式第一次加载时会稍慢,在高并发环境会有缺陷,但是一般能够满足需求。

    5、静态内部类单例模式

      public class Singleton {  
      private Singleton (){
      }
      public static final Singleton getInstance() {  
          return SingletonHolder.INSTANCE;  
      } 
      /**
      *静态内部类
      */
      private static class SingletonHolder {  
      private static final Singleton INSTANCE = new Singleton();  
      }   
    }
    

    这种是推荐使用的单例模式实现方式。当第一次加载Singleton类时并不会初始化INSTANCE,只有在第一次调用getInstance方法时才会导致INSTANCE被初始化。这种方式不仅能够保证线程安全,也能保证单例对象的唯一性,同时也延长了单例的实例化。

    6、枚举单例

     public enum Singleton {  
     INSTANCE;  
     public void whateverMethod() {  
     }  
     } 
    

    这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。

    Android源码中的单例模式

    在Android系统中,我们经常会通过Context获取系统级别的服务,如WindowsManagerService、ActivityManagerService等,更常用的是一个LayoutInflater的类,这些服务会在合适的时候以单例的形式注册在系统中,在我们需要的时候就通过Context的getSystemService(String name)获取。

    总结

    优点:
    (1)由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁的创建、销毁时,而且创建或销毁时性能又无法优化,单例模式的优势就非常明显。
    (2)单例模式可以避免对资源的多重占用,例如一个文件操作,由于只有一个实例存在内存中,避免对同一资源文件的同时操作。
    (3)单例模式可以在系统设置全局的访问点,优化和共享资源访问,例如,可以设计一个单例类,负责所有数据表的映射处理。

    缺点:
    (1)单例模式违背了面向对象开闭原则,不能通过接口扩展,若要扩展,只能修改代码来实现。
    (2)单例对象如果持有Context,那么很容易引发内存泄露。此时需要注意传递给单例对象的Context最好是Application Context。


    点赞加关注是给我最大的鼓励!

    相关文章

      网友评论

        本文标题:Android 设计模式-单例模式(Singleton Patt

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