Android多种单例模式的使用
2016-01-13 23:00
525 查看
单例模式的简单定义:
单例模式是应用最广的模式之一,确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,应用在一些创建对象需要消耗较多资源的地方。
单例模式的实现方式,在这里讲解了5种:1.懒汉模式,2.Double CheckLock(DCL)实现单例,3.静态内部类,4.枚举单例,5.使用容器实现单例模式。
OK,现在我们来一一的看一下他们的实现方式分别是什么:
1、懒汉模式是申明一个静态变量,在用户第一次调用getInstance时进行初始化
这种懒汉模式每一次调用都需要进行同步,造成不必要的开销(一般不建议使用)
饿汉模式的话就在类加载的时候直接初始化 private static Singleton instance = new Singleton();
2、DCL实现单例,优点是能够在需要时才初始化,又能保证线程安全且单例对象初始化后调用getInstance不进行同步锁
instance = new Singleton();的实际操作:
1.给Singleton分配内存,2调用Singleton的构造函数,初始化成员字段,3将instance对象指向分配的内存空间
但是Java编译器允许处理器乱序执行,已经JDK1.5之前JMM(Java Memory Model)中Cache,寄存器到主内存回写顺序的规定执行顺序可能是123,也可能是132,如果是132就会出现instance不是空,但是使用的时候会有问题,1.6开始已经作了调整,利用
Private volatile static Singleton instance = null;就可以保证安全性,但是会消耗一些性能
优点:资源资源利用率高,是使用最多的单利实现方式,可以满足绝大多数的单例,但是在一些高并发或者JDK1.6版本以下使用会有创建失败的可能性
3、静态内部类的单例模式,DCL存在一定的失效概率问题,所以我们可以使用以下代码来代替:
第一次加载Singleton时不会初始化sInstance,只有第一次调用getInstance的时候才会初始化,因此导致虚拟机加载SingletonHolder类,这种方式不仅能保证线程安全,也能保证唯一性和延迟加载,推荐使用
4、使用枚举类来完成单例模式
反序列化:在上述的集中单例模式中,反序列化会导致对象的重新创建(即使构造方法是私有的也会),但是反序列化操作提供了一个很特别的函数readResolve(),这个方法可以控制对象的反序列化;
但是,默认枚举类实例是线程安全的,并且在任何情况下它都是一个单例也不会受到反序列化的影响
5、使用容器实现单例模式的管理,这种模式重点在于对单例模式的管理
在程序初始化的时候将多种单例类注入到统一的管理类中,再用key进行获取
单例模式是应用最广的模式之一,确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,应用在一些创建对象需要消耗较多资源的地方。
单例模式的实现方式,在这里讲解了5种:1.懒汉模式,2.Double CheckLock(DCL)实现单例,3.静态内部类,4.枚举单例,5.使用容器实现单例模式。
OK,现在我们来一一的看一下他们的实现方式分别是什么:
1、懒汉模式是申明一个静态变量,在用户第一次调用getInstance时进行初始化
public class Singleton{ private static Singleton instance; private Singleton(){} public static synchronized Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } }
这种懒汉模式每一次调用都需要进行同步,造成不必要的开销(一般不建议使用)
饿汉模式的话就在类加载的时候直接初始化 private static Singleton instance = new Singleton();
2、DCL实现单例,优点是能够在需要时才初始化,又能保证线程安全且单例对象初始化后调用getInstance不进行同步锁
public class Singleton{ private static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ if(instance == null){ //主要为了避免不必要的同步 synchronized(Singleton.class){ if(instance == null){ //为了在空的情况下创建实例 instance = new Singleton(); } } } return instance; } }
instance = new Singleton();的实际操作:
1.给Singleton分配内存,2调用Singleton的构造函数,初始化成员字段,3将instance对象指向分配的内存空间
但是Java编译器允许处理器乱序执行,已经JDK1.5之前JMM(Java Memory Model)中Cache,寄存器到主内存回写顺序的规定执行顺序可能是123,也可能是132,如果是132就会出现instance不是空,但是使用的时候会有问题,1.6开始已经作了调整,利用
Private volatile static Singleton instance = null;就可以保证安全性,但是会消耗一些性能
优点:资源资源利用率高,是使用最多的单利实现方式,可以满足绝大多数的单例,但是在一些高并发或者JDK1.6版本以下使用会有创建失败的可能性
3、静态内部类的单例模式,DCL存在一定的失效概率问题,所以我们可以使用以下代码来代替:
public class Singleton{ private Singleton(){} public static Singleton getInstance(){ return SingletonHolder.sInstance; } /** *静态内部类 */ private static SingletonHolder{ private static final Singleton sInstance = new Singleton(); } }
第一次加载Singleton时不会初始化sInstance,只有第一次调用getInstance的时候才会初始化,因此导致虚拟机加载SingletonHolder类,这种方式不仅能保证线程安全,也能保证唯一性和延迟加载,推荐使用
4、使用枚举类来完成单例模式
public enum SingletonEnum(){ INSTANCE; public void doSomething(){ System.out.println("==="); } }
反序列化:在上述的集中单例模式中,反序列化会导致对象的重新创建(即使构造方法是私有的也会),但是反序列化操作提供了一个很特别的函数readResolve(),这个方法可以控制对象的反序列化;
private Object readResolve() throws ObjectStreamException{ return sInstance; }
但是,默认枚举类实例是线程安全的,并且在任何情况下它都是一个单例也不会受到反序列化的影响
5、使用容器实现单例模式的管理,这种模式重点在于对单例模式的管理
public class SingletonManager{ private static Map<String,Object> objMap = new HashMap<String,Object>(); private Singleton(){} public static void registerService(String key, Object instance){ if(!objMap.containsKey(key)){ objMap.put(key,instance); } public static Object getService(String){} return objMap.get(key); } }
在程序初始化的时候将多种单例类注入到统一的管理类中,再用key进行获取
相关文章推荐
- android hwcomposer 在视频播放中的应用
- Android Design Support Library(3)- Snackbar的使用
- Android自定义dialog中的EditText无法弹出键盘的解决
- android137 360 双击三击事件
- android animation rotate to specific angle
- android studio获取sha1的值mac版
- ScrollView中嵌套ListView/ExpandableListView显示问题
- Android Binder机制学习计划
- Android--listView的divider分割线样式和边距
- Android Studio 中使用Java 8 特性
- android星星评分自定义控件
- android 初始开发小问题
- android利用xmpp进行即时通信
- Android中怎么用this
- 我的Android进阶之旅------>Android Activity的singleTask加载模式和onActivityResult方法之间的冲突
- Android应用开发中模拟按HOME键效果
- 一些Android大牛的博客链接收集
- android学习项目
- 浅谈Android控件中的ListView优化
- Android客户端与服务器通信方式浅谈