Android 单例模式

定义: 保证一个类仅有一个实例,并提供一个访问它的全局访问点

1.饿汉模式

Android 单例模式_第1张图片

这种方式在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快.这种方式基于类加载机制,避免了多线程的同步问题.在类加载的时候就完成了实例化,没有达到懒加载的效果.如果从始至终未使用过这个实例,则会造成内存的浪费.

2. 懒汉模式(线程不安全)

Android 单例模式_第2张图片

懒汉模式声明了一个静态对象,在用户第一次调用时初始化.这虽然节约了资源,但第一次加载时需要实例化,反应稍慢一些,而且在多线程是不能正常工作

3.懒汉模式(线程安全)

Android 单例模式_第3张图片

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

4.双重检查模式(DCL)

 Android 单例模式_第4张图片

这种写法在getInstance 方法中对Singleton 进行了两次判空;第一次是为了不必要的同步, 第二次是在singleton 等于null 的情况下才创建实例.这里使用volatile 会或多或少的影响性能,但考虑到程序的正确性,牺牲这点性能还是值得的.DCL 的优点是资源利用率高.第一次执行getInstance时单例对象才被实例化,效率高.其缺点是第一次加载时反应稍慢一些,在高并发环境下也有一定的缺陷.DCL 虽然一定程度上解决了资源消耗和多余的同步,线程安全等问题,但其还是在某些情况下会出现失效的问题,也就是DCL失效.这里建议用静态内部类单例模式来代替DCL.

5.静态内部类单例模式

Android 单例模式_第5张图片

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

6. 枚举单例模式 

Android 单例模式_第6张图片

默认枚举实例的创建是线程安全的,并且在任何情况下都是单例.在上面讲的几种单例模式实现中.有一种情况下会重新创建对象,那就是反序列化;讲一个单例实例对象写到磁盘再读回来,从而获得了一个实例.反序列化操作提供了readResolve 方法,这个方法可以让开发人员控制对象的反序列化.在上述几个方法实例中,如果要杜绝单例对象被反序列化时重新生成对象,就必须加入如下方法:

private Object readResolve() throws ObjectStreamException{
    return singleton;
}

枚举单例的优点就是简单,但是大部分应用开发很少用枚举,其可读性并不是很高.

 

二 单例模式的使用场景

在一个系统中,要求一个类有且仅有一个对象,它的具体使用场景如下:

整个项目需要一个共享访问点或者共享数据

创建一个对象需要耗费的资源过多,比如访问I/O 或者数据库等资源

工具类对象.

你可能感兴趣的:(Android 单例模式)