《Android源码设计模式》--单例模式
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源码设计模式》--单例模式的更多相关文章
- <人人都懂设计模式>-单例模式
这个模式,我还是了解的. 书上用了三种不同的方法. class Singleton1: # 单例实现方式1 __instance = None __is_first_init = False def ...
- <人人都懂设计模式>-装饰模式
书上,真的用一个人穿衣打拌来讲解装饰模式的呢. from abc import ABCMeta, abstractmethod class Person(metaclass=ABCMeta): def ...
- <人人都懂设计模式>-中介模式
真正的用房屋中介来作例子, 好的书籍总是让人记忆深刻. class HouseInfo: def __init__(self, area, price, has_window, has_bathroo ...
- <人人都懂设计模式>-状态模式
同样是水,固态,气态,液态的变化,是由温度引起. 引此为思考状态模式. from abc import ABCMeta, abstractmethod # 引入ABCMeta和abstractmeth ...
- 人人都懂区块链--pdf电子版学习资料下载
人人都懂区块链 21天从区块链“小白”到资深玩家电子版pdf下载 链接:https://pan.baidu.com/s/1TWxYv4TLa2UtTgU-HqLECQ 提取码:6gy0 好的学习资料需 ...
- 【人人都懂密码学】一篇最易懂的Java密码学入门教程
密码与我们的生活息息相关,远到国家机密,近到个人账户,我们每天都在跟密码打交道: 那么,密码从何而来?生活中常见的加密是怎么实现的?怎么保证个人信息安全?本文将从这几方面进行浅谈,如有纰漏,敬请各位大 ...
- 人人都懂的HTML基础知识-HTML教程(1)
01.HTML基础简介 HTML (HyperText Markup Language,超文本标记语言) 不是一门编程语言,而是一种用于定义内容结构的标记语言,用来描述网页内容,文件格式为.html. ...
- JavaScript设计模式-单例模式、模块模式(转载 学习中。。。。)
(转载地址:http://technicolor.iteye.com/blog/1409656) 之前在<JavaScript小特性-面向对象>里面介绍过JavaScript面向对象的特性 ...
- 设计模式 单例模式(Singleton) [ 转载2 ]
设计模式 单例模式(Singleton) [ 转载2 ] @author java_my_life 单例模式的结构 单例模式的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类 ...
- 设计模式 单例模式(Singleton) [ 转载 ]
设计模式 单例模式(Singleton) [ 转载 ] 转载请注明出处:http://cantellow.iteye.com/blog/838473 前言 懒汉:调用时才创建对象 饿汉:类初始化时就创 ...
随机推荐
- div+css+jQuery简单实现投票功能
昨天看到C#群里有人问一个投票功能如何实现... 我对此很感兴趣,为了练习一下,就有了以下代码. 投票功能使用jQuery实现..纯html代码...数据通过json字符串传递,通过 eval转换为j ...
- Linux系统接入小区宽带
jollywing(jollywing@foxmail.com) 安装 rp-pppoe 今天去联通营业厅开通了家庭宽带,回到家就搜索怎么用Linux接入小区宽带,发现大多数人都选择用PPPOE拨号上 ...
- 【BZOJ】2006: [NOI2010]超级钢琴
[题意]给定长度为n的整数序列,求长度为[L,R]的前k大区间和的和.n,k<=500000. [算法]堆+贪心+RMQ [题解]考虑暴力是取所有长度为[L,R]的子串的前k大求和,复杂度O(n ...
- 20155303 2016-2017-2 《Java程序设计》第一周学习总结
20155303 2016-2017-2 <Java程序设计>第一周学习总结 教材学习内容总结 浏览教材,根据自己的理解每章提出一个问题 Chapter1 Java平台概论:MyProgr ...
- 20165230 2017-2018-2 《Java程序设计》第6周学习总结
20165230 2017-2018-2 <Java程序设计>第6周学习总结 教材学习内容总结 第八章 常用使用类 String类常用方法 public int length() publ ...
- 查看linux系统的信息
#!/bin/sh ################################################## #function:get host's information #Autho ...
- 查看oracle数据库日志存放位置
1,默认情况下,oracle的日志文件记录在$ORACLE/rdbms/log目录下 [oracle@oracle log]$ pwd /home/oracle/oracle/product/11.2 ...
- vue表格中显示金额格式化与保存时格式化为数字并校验!
最近项目中遇到了成本计算的,需要显示金额,保存一下,以后方便直接拿来用! 一 数字转金额格式显示 //数字转金额格式 format:function(s){ if(/[^0-9\.]/.test(s) ...
- 【黑客免杀攻防】读书笔记15 - 源码免杀、C++壳的编写
1.源码免杀 1.1 定位产生特征的源码 定位文件特征 1.根据MyCCL的特征码定位工具,定位出有特征的地址 2.根据VS的反汇编窗口,输入有特征的地址得到特征地址与源码的关系 3.插入Messag ...
- 正则表达式基础->
描述:(grep) 正则表达式是一种字符模式,用于在查找过程中匹配指定的字符.在大多数程序里,正则表达式都被置于两个正斜杠之间,它匹配被查找的行中任何位置出现的相同模式 基础正则表达式 正则表达式 描 ...