No1:

懒汉单例模式优缺点分析

  1. public class Singleton{
  2. private static Singleton instance;
  3. private Singleton(){}
  4.  
  5. public static synchronized Singleton getInstance(){
  6. if(instance == null){
  7. instance = new Singleton();
  8. }
  9. return instance;
  10. }
  11. }

优点:单例只有在使用时才会被实例化,在一定程度上节约了资源

缺点:第一次加载时需要及时进行实例化,反应稍慢,最大的问题是每次调用getInstance都进行同步,造成不必要的同步开销。

所以这种模式一般不建议使用

No2:

Double Check Lock(DCL)双重检查锁定方式

  1. public class Singleton{
  2. private static Singleton sInstance = null;
  3. private Singleton(){}
  4.  
  5. public void doSomething(){
  6. System.out.println("do sth.");
  7. }
  8.  
  9. public static Singleton getInstance(){
  10. if(mInstance == null){
  11. synchronized(Singleton.class){
  12. if(mInstance == null){
  13. sInstance = new Singleton();
  14. }
  15. }
  16. }
  17. return sInstance;
  18. }
  19. }

优点:,第一次执行getInstance时单例对象才会被实例化,资源利用率高。第一层对instance判空主要是为了避免不必要的同步,第二层判断则是为了在null的情况下创建实例

缺点:第一次加载时反应稍慢,也由于java内存模型的原因偶尔会失败。再高并发环境下也有一定缺陷,虽然发生概率很小

No3:

静态内部类单例模式

  1. public class Singleton{
  2. private Singleton(){}
  3. public static Singleton getInstance(){
  4. return SingletonHolder.sInstance;
  5. }
  6.  
  7. /**
  8. *静态内部类
  9. */
  10. private static class SingletonHolder{
  11. private static final Singleton sInstance = new Singleton();
  12. }
  13. }

第一次调用getInstance方法会导致虚拟机加载SingletonHolder类,这种方式不仅能够确保线程安全,也能够保证单例对象的唯一性,同时也延迟了单例的实例化,所以推荐使用

No4:

枚举单例

  1. public enum SingletonEnum{
  2. INSTANCE;
  3. public void doSomething(){
  4. System.out.println("do sth.");
  5. }
  6. }

优点:线程安全,即使反序列化也不会重新生成新的实例

No5:

如果想杜绝单例模式对象在被反序列化时重新生成对象,那么必须加入readResolve函数

  1. public final class Singleton implements Serializable{
  2. private static final long serialVersionUID = 0L;
  3. private static final Singleton INSTANCE = new Singleton();
  4.  
  5. private Singleton(){}
  6.  
  7. public static Singleton getInstance(){
  8. return INSTANCE;
  9. }
  10.  
  11. private Object readResolve() throws ObjectStreamException{
  12. return INSTANCE;
  13. }
  14. }

也就是在readResolve方法中将单例对象返回,而不是重新生成一个新的对象。而对于枚举,并不存在这个问题

No6:

1)可序列化类中的字段类型不是Java的内置类型,那么该字段类型也需要实现Serializable接口

2)如果调整了可序列化类的内部结构,例如新增、去除某个字段,但没有修改serialVersionUID,会引发异常。最好的方案是将值设置为0L,只是那些新修改的字段会为0或者null。

No7:

使用容器实现单例模式

  1. public class SingletonManager{
  2. private static Map<String,Object> objMap = new HashMap<String,Object>();
  3.  
  4. private SingletonManager(){}
  5.  
  6. public static void registerService(String key,Object instance){
  7. if(!objMap.containsKey(key)){
  8. objMap.put(key,instance);
  9. }
  10. }
  11.  
  12. public static Object getService(String key){
  13. return objMap.get(key);
  14. }
  15. }

优点:可以管理多种类型的单例,并且在使用时可以通过统一的接口进行获取操作,降低了用户的使用成本,也对用户隐藏了具体实现,降低了耦合度。

No8:

LayoutInflater.from(Context)来获取LayoutInflater服务

Context是抽象类,在Application、Activity、Service中都会存在一个Context对象,即Context的总个数为Activity个数+Service个数+1。

一个Activity的入口是ActivityThread的main函数。

创建Context对象的实现类是ContextImpl

No9:

从ContextImpl类的部分代码中可以看到,在虚拟机第一次加载该类时会注册各种ServiceFetcher,其中就包含了LayoutInflater Service。将这些服务以键值对的形式存储在一个HashMap中,用户使用时只需要根据key来获取到对应的ServiceFetcher,然后通过ServiceFetcher对象的getService函数来获取具体的服务对象。当第一次获取时,会调用ServiceFetcher的createService函数创建服务对象,然后将该对象缓存到一个列表中,下次再取值时直接从缓存中获取,避免重复创建对象,从而达到单例的效果。系统核心服务以单例形式存在,减少了资源消耗。

No10:

LayoutInflater是一个抽象类,PolicyManager实际上是一个代理类,实现了IPolicy接口

真正LayoutInflater的实现类是PhoneLayoutInflater

No11:

Activity的setContentView方法实际上调用的是Window的setContentView,Window是一个抽象类,具体实现类是PhoneWindow

No12:

createView相对比较简单,如果有前缀,那么构造View的完整路径,并且将该类加载到虚拟机中,然后获取该类的构造函数并且缓存起来,再通过构造函数来创建该View的对象,最后将View对象返回,这就是解析单个View的过程。通过rInflate的解析之后,整棵视图树就构建完毕。

No13:

单例模式的缺点:

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

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

No14:

Window的View层级图

《Android源码设计模式》--单例模式的更多相关文章

  1. <人人都懂设计模式>-单例模式

    这个模式,我还是了解的. 书上用了三种不同的方法. class Singleton1: # 单例实现方式1 __instance = None __is_first_init = False def ...

  2. <人人都懂设计模式>-装饰模式

    书上,真的用一个人穿衣打拌来讲解装饰模式的呢. from abc import ABCMeta, abstractmethod class Person(metaclass=ABCMeta): def ...

  3. <人人都懂设计模式>-中介模式

    真正的用房屋中介来作例子, 好的书籍总是让人记忆深刻. class HouseInfo: def __init__(self, area, price, has_window, has_bathroo ...

  4. <人人都懂设计模式>-状态模式

    同样是水,固态,气态,液态的变化,是由温度引起. 引此为思考状态模式. from abc import ABCMeta, abstractmethod # 引入ABCMeta和abstractmeth ...

  5. 人人都懂区块链--pdf电子版学习资料下载

    人人都懂区块链 21天从区块链“小白”到资深玩家电子版pdf下载 链接:https://pan.baidu.com/s/1TWxYv4TLa2UtTgU-HqLECQ 提取码:6gy0 好的学习资料需 ...

  6. 【人人都懂密码学】一篇最易懂的Java密码学入门教程

    密码与我们的生活息息相关,远到国家机密,近到个人账户,我们每天都在跟密码打交道: 那么,密码从何而来?生活中常见的加密是怎么实现的?怎么保证个人信息安全?本文将从这几方面进行浅谈,如有纰漏,敬请各位大 ...

  7. 人人都懂的HTML基础知识-HTML教程(1)

    01.HTML基础简介 HTML (HyperText Markup Language,超文本标记语言) 不是一门编程语言,而是一种用于定义内容结构的标记语言,用来描述网页内容,文件格式为.html. ...

  8. JavaScript设计模式-单例模式、模块模式(转载 学习中。。。。)

    (转载地址:http://technicolor.iteye.com/blog/1409656) 之前在<JavaScript小特性-面向对象>里面介绍过JavaScript面向对象的特性 ...

  9. 设计模式 单例模式(Singleton) [ 转载2 ]

    设计模式 单例模式(Singleton) [ 转载2 ] @author java_my_life 单例模式的结构 单例模式的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类 ...

  10. 设计模式 单例模式(Singleton) [ 转载 ]

    设计模式 单例模式(Singleton) [ 转载 ] 转载请注明出处:http://cantellow.iteye.com/blog/838473 前言 懒汉:调用时才创建对象 饿汉:类初始化时就创 ...

随机推荐

  1. ElasticSearch关键概念

    Elasticsearch 添加索引 一个存储关联数据的地方 用来指向一个或者多个分片(shards)的逻辑命名空间(logical namespcase) 应用程序直接与索引通信 一个分片(shar ...

  2. centos无法通过ssh连接的解决

    系统环境是centos7,虚拟机环境下的.在使用ssh工具连接虚拟机的时候发现连接不上,用的是root 先检查openssh-server是否安装: yum list installed | grep ...

  3. 同一个IIS绑定多个Htts 站点问题

    默认情况一个服务器的IIS只能绑定一个HTTPS也就是443端口 要实现多个站点对应HTTPS只能更改IIS配置 地址:C:Windowssystem32inetsrvconfigapplicatio ...

  4. Sparse AutoEncoder简介

    1. AutoEncoder AutoEncoder是一种特殊的三层神经网络, 其输出等于输入:\(y^{(i)}=x^{(i)}\), 如下图所示: 亦即AutoEncoder想学到的函数为\(f_ ...

  5. 【转】WPF绑定模式

    源地址:http://www.cnblogs.com/zjz008/archive/2010/05/26/1744802.html http://blog.csdn.net/haylhf/articl ...

  6. 【转】C#使用PrintDocument打印 多页 打印预览

    PrintDocument实例所有的订阅事件如下: 创建一个PrintDocument的实例.如下: System.Drawing.Printing.PrintDocument docToPrint ...

  7. canvas画布,写字板

    <!doctype html><html><head> <meta charset="utf-8"> <meta http-e ...

  8. Informatica学习:2、配置存储库服务和集成服务

    继续上一篇的1.安装介质的获取与安装,本文介绍服务端的存储库服务和集成服务的配置. 安装好Informatica的客户端和服务端后,需要登陆Administration Console,配置存储库服务 ...

  9. beego项目运行过程

    一:首先man.go,整个程序的入口 func main() { beego.Run() } 然后beego.run()代码 // Run beego application. // beego.Ru ...

  10. Django-ORM简介

    ORM简介 MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库 ORM是“对象-关系-映射”的简称 ...