美文网首页
Android设计模式(单例模式)

Android设计模式(单例模式)

作者: 积木Blocks | 来源:发表于2019-02-13 15:20 被阅读0次

目录


  • 1.单例模式简介
  • 2.单例模式关键点
  • 3.单例模式UML图
  • 4.单例模式的实现方式
    • 饿汉式
    • 懒汉式
    • 同步锁懒汉式
    • DCL懒汉式
    • 枚举
    • 静态内部类
  • 5.使用场景
  • 6.单例模式和静态类的区别
  • 7.单例模式相关面试题

1.单例模式(Singleton)

  • 最基础,使用最广泛的设计模式
  • 创建型设计模式
  • 一个类有且仅有一个实例,并且自行实例化向整个系统提供

2.单例模式关键点

  • 构造函数私有化,即声明为private
  • 通过一个静态方法或者枚举返回单例类对象
  • 确保单例类的对象有且只有一个,尤其要注意多线程的场景
  • 确保单例类对象在反序列化时不会重新创建对象

3.单例模式UML图


4.单例模式的实现方式


4.1 饿汉式单例(Eager Singleton)
public class Singleton {
    //1.创建私有静态成员变量并实例化
    private static Singleton mSingleton = new Singleton();

    //2.将构造函数私有化,使外界无法直接实例化
    private Singleton() {
    }

    //3.提供公开方法返回创建的实例化对象
    public static Singleton getInstance() {
        return mSingleton;
    }
}
  • 优点:类加载的时候,会创建Singleton 实例。并且因为虚拟机保证了类只会加载一次,所以这种写法保证线程的安全性
  • 缺点:也是由于类加载的时候就会创建实例,会降低内存的使用率,浪费不必要的资源。如果单例类使用频繁的情况下,可以使用这种方式。
  • 访问量大或者访问线程较多的时候,可以使用饿汉式。以空间换时间
4.2 经典的懒汉式单例(Lazy Singleton)【不推荐】
public class Singleton {

    private Singleton() {}

    private static Singleton instance=null;

    public static Singleton getInstance() {
         if (instance== null) {  
             instance= new Singleton();
         }  
        return instance;
    }
}
  • 优点:实现了懒加载,在第一次使用的时候才会实例化单例对象
  • 缺点:非线程安全,在多并发情况,可能出现多个Singleton 实例,导致单例失效。
  • 访问量小的时候,可以使用懒汉式。以时间换空间
4.3 加同步锁的懒汉式
public class Singleton {

    private Singleton() {}

    private static Singleton instance=null;

    public static synchronized Singleton getInstance() {
         if (instance== null) {  
             instance= new Singleton();
         }  
        return instance;
     }
}
4.4 DCL懒汉式
public class Singleton {
    private static Singleton instance = null;
    public  static Singleton getInstance() {
        if(null == instance) {    // 线程二检测到instance不为空
            synchronized (Singleton.class) {
                if(null == instance) {                    
                    instance = new Singleton();    // 线程一被指令重排,先执行了赋值,但还没执行完构造函数(即未完成初始化)    
                }
            }
        }
       
        return instance;    // 后面线程二执行时将引发:对象尚未初始化错误
    }
}
  • 优点:资源利用效率高,第一次执行getInstance时单例对象才会被实例化,效率高
  • 缺点:第一次加载时反应稍慢,也由于Java内存模型的原因偶尔会失败。高并发环境下也有一定的缺陷,虽然发生的概率比较小。
4.5 枚举 【不推荐】
enum Singleton{
    INSTANCE;
}
  • 优点:线程安全,防止反序列化重新创建新的对象
  • 缺点:没有实现懒加载,并且Android中不推荐用枚举,内存消耗较大。
4.6 静态内部类【推荐】
public class Singleton {

    private Singleton(){
    }

    private static class SingletonHolder{
        private final static Singleton instance=new Singleton();
    }

    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }

}

静态内部类因为只会加载一次,所以保证了线程安全。
内部类是在第一次使用的时候才会进行加载,实现了懒加载


5.单例模式的使用场景

  • 需要频繁的进行创建和销毁的对象;
  • 创建对象时耗时过多或耗费资源过多,但又经常用到的对象;
  • 工具类对象;
  • 频繁访问数据库或文件的对象。
  • 确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有且只有一个

6.单例模式和静态类的区别

http://blog.sina.com.cn/s/blog_4adc4b090102w1j1.html


7.单例模式相关面试题

一般引入单例模式的相关问题有两种情况,一是简单粗暴直接问你会什么设计模式,二是问你第三方的框架,然后问框架用了哪些设计模式,比如EventBus用了DCL的单例。

  • 问题1.单例的写法,UML图,以及各种写法的优点和缺点?(可能需要手写单例)
    • 单例写法比较多,我这里记录了6种,还有其他的方式,比如容器。能写出常见几种就行。
  • 问题2.什么情况下使用单例?(毕竟设计模式不能滥用)
  • 问题3.构成单例模式的关键点?
  • 问题4.单例和静态类的区别?

相关文章

网友评论

      本文标题:Android设计模式(单例模式)

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