No1:

懒汉单例模式优缺点分析

public class Singleton{
private static Singleton instance;
private Singleton(){} public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}

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

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

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

No2:

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

public class Singleton{
private static Singleton sInstance = null;
private Singleton(){} public void doSomething(){
System.out.println("do sth.");
} public static Singleton getInstance(){
if(mInstance == null){
synchronized(Singleton.class){
if(mInstance == null){
sInstance = new Singleton();
}
}
}
return sInstance;
}
}

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

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

No3:

静态内部类单例模式

public class Singleton{
private Singleton(){}
public static Singleton getInstance(){
return SingletonHolder.sInstance;
} /**
*静态内部类
*/
private static class SingletonHolder{
private static final Singleton sInstance = new Singleton();
}
}

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

No4:

枚举单例

public enum SingletonEnum{
INSTANCE;
public void doSomething(){
System.out.println("do sth.");
}
}

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

No5:

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

public final class Singleton implements Serializable{
private static final long serialVersionUID = 0L;
private static final Singleton INSTANCE = new Singleton(); private Singleton(){} public static Singleton getInstance(){
return INSTANCE;
} private Object readResolve() throws ObjectStreamException{
return INSTANCE;
}
}

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

No6:

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

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

No7:

使用容器实现单例模式

public class SingletonManager{
private static Map<String,Object> objMap = new HashMap<String,Object>(); private SingletonManager(){} public static void registerService(String key,Object instance){
if(!objMap.containsKey(key)){
objMap.put(key,instance);
}
} public static Object getService(String key){
return objMap.get(key);
}
}

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

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. SQL语句(十七)综合练习_分组查询_内嵌查询_视图使用

    Select * from Student Select * From Course Select * from SC --子查询 低于总平均成绩的女同学成绩 Select Grade from St ...

  2. 【转】MYSQL数据库设计规范与原则

    转载出:http://www.cnblogs.com/lovekingly/p/5044278.htmlMYSQL数据库设计规范 1.数据库命名规范 采用26个英文字母(区分大小写)和0-9的自然数( ...

  3. Writing your first academic paper

    Writing your first academic paper If you are working in academics (and you are if you are working wi ...

  4. Java并发编程原理与实战二十一:线程通信wait&notify&join

    wait和notify wait和notify可以实现线程之间的通信,当一个线程执行不满足条件时可以调用wait方法将线程置为等待状态,当另一个线程执行到等待线程可以执行的条件时,调用notify可以 ...

  5. 轻松使用div模拟select下拉菜单

    没有办法,平时不是万不得已我是不喜欢去模拟各类控件的,一个是麻烦,二个是对性能也有些影响,还是原生的来的实在.老板昨天发话,必须模拟赶紧的,老外最喜欢简洁干净的风格,说的貌似都很在理的样子,业务部也是 ...

  6. python读写mysql

    读取mysql数据 # -*- coding: utf-8 -*- # 导入必要模块 import pandas as pd from sqlalchemy import create_engine ...

  7. Linux基础-awk使用

    打印uid在30~40范围内的用户名:awk -F: '$3>=30&&$3<040{print $1}' passwd 打印第5-10行的行号和用户名:awk -F: ' ...

  8. nginx安装Lets Encrypt SSL免费HTTPS加密证书

    Linux Nginx网站:Certbot安装配置Lets Encrypt SSL免费HTTPS加密证书 原文地址:https://renwole.com/archives/157 实验环境:Cent ...

  9. 查看 CUDA cudnn 版本

    cuda 版本 cat /usr/local/cuda/version.txt cudnn 版本 cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MA ...

  10. Material Design In Action——重构bilibili客户端

    前言 哔哩哔哩动画是中国大陆的一家弹幕视频网站,在中国二次元用户中颇受欢迎. 哔哩哔哩动画之前推出过采用 Android Design 的 Android 客户端,虽然有使用了部分过时控件(例如 Sc ...