(其实设计模式应该从属于java,但是会专门针对android做相应的解释,所以就取名为android设计模式~)

一.单例模式的介绍

单例模式是应用最广的模式之一,在应用这个模式的时候,单例对象的类必须保证只有一个实例存在。在android中的应用场景例如整个app只有一个application对象,只有一个ImageLoader对象等。

二.单例模式下的各种实现方式

1.饿汉模式

public class Singleton {

private Singleton() {} //在该类初始化的时候就会自行实例化

private static final Singleton single = new Singleton();

public static Singleton getInstance() {

return single;

}

}

2.懒汉模式

public class Singleton {

private Singleton(){}

private final static Singleton mInstance; //没有care线程安全的问题

public static Singleton getInstance() {

if(mInstance == null){

mInstance = new Singleton();

}

return mInstance;

}

}

Tips:不论是饿汉模式还是懒汉模式,可能在你的app中都占有一席之地。那么我们先来对比下两者的区别,首先饿汉模式会在该类初始化的时候就自动实例化,而懒汉模式则会在对应调用getInstance方法时才会对应的实例化,实现了实例的延时加载。设想如果该实例在app中不一定被使用到,那么使用懒汉模式就可以节省内存。但是懒汉模式会在第一次获取实例时较为耗时,饿汉模式由于在初始化类时就进行了实例化,第一次获取实例就不会耗时。

以上是针对饿汉模式和懒汉模式之间的区别做的分析,接下来我们来关注之前代码中对于懒汉模式线程不安全的问题。分别提供以下几种解决方案来进行对比:

2.1.在getInstance方法上加同步锁

public class Singleton {

private Singleton(){}

private final static Singleton mInstance; //加上同步锁

public static synchronized Singleton getInstance() {

if(mInstance == null){

mInstance = new Singleton();

}

return mInstance;

}

}

这种方法虽然解决了线程安全的问题,但是单例模式一般都是应用在一些会被频繁调用的场景上的,如果在每次获取实例的时候都需要去进行线程同步,那会增加不小的开销,会使单例的获取变的缓慢,这样就得不偿失了。那么我们继续改进,看下面的方法:

2.2.Double Check Lock(DCL)实现单例

public class Singleton {

private Singleton(){}

private final static Singleton mInstance;

/*双重锁定:只在第一次初始化的时候加上同步锁*/

public static Singleton getInstance() {

if(mInstance == null){

synchronized(Singleton.class){

if(mInstance == null){

mInstance = new Singleton();

}

}

}

return mInstance;

}

}```

这种双重锁定的方式,避免了每次获取实例时不必要的同步操作,只在第一次获取实例的时候才进行同步,将开销减到了最小,并且保证了线程安全。但是,真的是线程安全了么?问题其实出在mInstance = new Singleton();这句代码,虽然它只是一句代码,但是实际上它不是一个原子操作,这句代码最终会被编译成多条汇编指令,它大致做了3件事情:

(1)给Singleton的实例分配内存;

(2)调用Singleton()的构造函数,初始化成员字段;

(3)将mInstance对象指向分配的内存空间(此时mInstance就不是null了)。

由于Java编译器允许处理器乱序执行,以及JDK1.5之前JMM(Java Memory Model,即Java内存模型)中Cache、寄存器到内存回写顺序的规定,上面的第二和第三的顺序是无法保证的。也就是说,执行顺序可能是1-2-3也可能是1-3-2。如果是后者,并且在3执行完毕、2未执行之前,被切换到另一个线程上,就会出问题。但是在你的app没有太多的高并发存在时,这种模式已经可以完全满足大多数开发者的需求。那么一定还有更好的:

#### 2.3.静态内部类单例模式

```java

public class Singleton {

private Singleton(){}

private final static Singleton mInstance;

public static Singleton getInstance() {

return SingletonHolder.mInstance;

}

private static class SingletonHolder {

private final static Singleton mInstance = new Singleton();

}

}

当第一次加载Singleton类的时候并不会初始化mInstance,只有在第一次调用getInstance方法时才会导致mInstance被初始化。因此,第一次调用getInstance方法会导致虚拟机加载SingletonHolder类,这种方式不仅能够确保线程安全,也能够保证单例对象的唯一性,同时也延迟了单例的实例化,所以这是推荐使用的单例模式实现方式。Tip:java中的枚举其实也是单例的一种实现方式

三.结论

之前在对单例的了解并没有特别的系统,这次梳理了下,发现其实自己的工程中还是有很多不考虑线程安全的单例实现的,虽然在没有并发的情况下可能没有太大的影响,但是程序是需要有超前意识的,推荐大家也使用2.3的单例实现方式。

android 单例模式的使用场景,android设计模式之单例模式相关推荐

  1. android 单例模式的使用场景,Android设计模式—单例模式

    定义 确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 应用场景 确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多资源,或者某种类型的对象只应该有且只有一个.例如,创建一个对 ...

  2. android开发论坛!原生Android开发的路该怎么走?系列篇

    前阵子,我和阿里的薪酬福利专家M同学聊了一下午,M同学做了9年薪酬,和我们吐槽了很多薪酬方面的现象,也道出了少有人关注的薪酬逻辑和常识. 这一次,我又找了一位阿里技术岗位的招聘专家T同学,从他的视角中 ...

  3. java设计模式--1.单例模式

    单例模式的定义与特点 单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式.例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗 ...

  4. android edittext不可复制_精选Android中高级面试题:性能优化,JNI,设计模式

    性能优化 1.图片的三级缓存中,图片加载到内存中,如果内存快爆了,会发生什么?怎么处理? 参考回答:首先我们要清楚图片的三级缓存是如何的: 如果内存足够时不回收.内存不够时就回收软引用对象 2.内存中 ...

  5. Android开发笔记(八十九)单例模式

    基本概念 单例模式是一种常用的软件设计模式,它确保一个类只有一个实例,从而方便对实例个数的控制并节约系统资源. 单例模式有三个特点: 1.某个类只能有一个实例: 2.它要自行创建这个实例: 3.它只有 ...

  6. Android单例模式和线程安全,Android 开发单例模式线程安全与序列化

    前言 单例模式是最常用到的设计模式之一,熟悉设计模式的朋友对单例模式都不会陌生.一般介绍单例模式都只会提到饿汉式和懒汉式这两种实现方式. 看完本章后,你可能会发现项目中的并没有正确的使用创建单例,本文 ...

  7. 设计模式之——单例模式(Singleton)的常见应用场景(转):

    单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此 ...

  8. Android框架源码分析——从设计模式角度看 Retrofit 核心源码

    Android框架源码分析--从设计模式角度看 Retrofit 核心源码 Retrofit中用到了许多常见的设计模式:代理模式.外观模式.构建者模式等.我们将从这三种设计模式入手,分析 Retrof ...

  9. Android阿面试积累,android项目开发实战密码

    公差为1的等差数列求和,如何优化 自己的优势在哪里 注解如何获取,反射为何耗性能? Java的GC机制,分代回收策略 Binder机制:ServiceManager什么时候注册的? int,long的 ...

最新文章

  1. 在JAVA EE中配置hibernate以及hibernate hello world
  2. R语言问题解决:Error: Discrete value supplied to continuous scale
  3. 赵雪轩:数据科学助力我的智能化航天梦 | 提升之路系列
  4. 运维杂记(二):打印机print spooler服务自动关闭
  5. Java 编程的动态性, 第4部分: 用 Javassist 进行类转换--转载
  6. 轻量级的日期时间控件Pikaday
  7. JQuery中的元素选择器
  8. Enterprise Spring示例和集成测试
  9. shell多线程执行ping
  10. PROFIBUS-DP现场总线的结构及应用
  11. 刷新计算机dns缓存的命令,电脑如何刷新dns缓存【图解】
  12. 微信群如何设置永久有效二维码?99.99%的人都不知道!
  13. 政府12345便民服务热线 -- MICC全媒体智能呼叫中心建设方案
  14. python提速网站资源_三分钟学会Django缓存,让你的网站提速十倍以上
  15. 花之语第五期:紫罗兰
  16. 纯html+css实现点击切换tab页
  17. Extrinsic Calibration of a Camera and Laser Range Finder (improves camera calibration)阅读笔记
  18. IPv4地址的分配原理
  19. Whitening Sentence Representations for Better Semantics and Faster Retrieval论文学习
  20. Axure预览和发布时去掉左上角的标识

热门文章

  1. Flutter Chip详解
  2. Jspxcms 无入侵式开发
  3. 10个镜像网站工具箱供你使用,不注册ChatGPT也能免费使用ChatGPT
  4. Terraform 实战:Terraform入门
  5. Google搜索技巧、使用Google的其它专业搜索
  6. 论中国世界文化遗产的保护与开发
  7. idea2020.03如何设置皮肤
  8. 【信贷业务】金融信贷存量客户运营管理
  9. WPF一个完整的GIF制作工具实例(Part3:生成GIF)
  10. 尚硅谷2020最新版宋红康JVM教程-16-垃圾回收相关概念