1. 秦子帅的博客首页
  2. Android

设计模式(1)-单例模式

点击标题下「蓝色微信名」可快速关注


单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例

设计模式(1)-单例模式

普通的单例模式写法如下:

设计模式(1)-单例模式

单例模式的优点

(1).由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁地创建、销毁时,而且创建或销毁时性能又无法优化,单例模式的优势就非常明显。 

(2).由于单例模式只生成一个实例,所以减少了系统的性能开销,当一个对象的产生需要比较多的资源时,比如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后用永久驻留内存的方式来解决。 

(3).单例模式可以避免对资源的多重占用,例如一个写文件操作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。 

(4).单例模式可以在系统设置全局的访问点,优化和共享资源访问,例如,可以设计一个单例类,负责所有数据表的映射处理。

设计模式(1)-单例模式

单例模式的缺点

(1).单例模式一般没有接口,扩展很困难,若要扩展,除了修改代码基本上没有第二种途径可以实现。 

(2).单例对象如果持有Context,那么很容易引发内存泄露,此时需要注意传给单例对象的Context最好是Application Context。

设计模式(1)-单例模式

单例模式的七种写法

1.(懒汉,线程不安全):

这种写法在多线程不能正常工作。


2.(懒汉,线程安全):

这种写法能够在多线程中很好的工作,但是效率很低,99%情况下不需要同步。


3.(饿汉):

饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。这种写法能够在多线程中很好的工作,但是每次调用getInstance方法时都需要进行同步,造成不必要的同步开销,而且大部分时候我们是用不到同步的。


4. 双重检查模式 (DCL)

这种写法在getSingleton方法中对singleton进行了两次判空,第一次是为了不必要的同步,第二次是在singleton等于null的情况下才创建实例。DCL优点是资源利用率高,第一次执行getInstance时单例对象才被实例化,效率高。缺点是第一次加载时反应稍慢一些,而且有失效的可能。


5. 静态内部类

第一次加载Singleton类时并不会初始化sInstance,只有第一次调用getInstance方法时虚拟机加载SingletonHolder 并初始化sInstance ,这样不仅能确保线程安全也能保证Singleton类的唯一性,很合理的单例模式。


6. 枚举

7. 使用容器

用SingletonManager 将多种的单例类统一管理,在使用时根据key获取对象对应类型的对象。用户使用时只需要根据key来获取到对应的ServiceFetcher,然后通过ServiceFetcher对象的getService函数获取具体的服务对象。当第一次获取时,会调用ServiceFetcher的creatService函数创建服务对象,然后将该对象缓存到一个列表中,下次再取时直接从缓存中获取,避免重复创建对象,从而达到单例的效果。Android中的系统核心服务以单例形式存在,减少了资源消耗。


设计模式(1)-单例模式

总结:

不管以哪种形式实现单例模式,它们的核心原理是将构造函数私有化,并且通过静态公有方法获取一个唯一的实例,在这个获取的过程中必须保证线程的安全,同时也要防止单例对象的资源消耗。


设计模式(1)-单例模式

推荐阅读

 


【收藏篇】32篇技术博文汇总


Android 架构师 | 资料分享 03


MediaPlayer实现金额的语音播报功能


设计模式(1)-单例模式

原文始发于微信公众号( 秦子帅 ):设计模式(1)-单例模式

发布者:秦子帅,转转请注明出处:http://qinzishuai.cn/index.php/2017/10/12/137c2ac26f/

联系我们

912241847

在线咨询:点击这里给我发消息

邮件:qzs531156@163.com

QR code