一、概述
1、概念
单例模式是一种对象创建模式,它用于产生一个对象的具体实例,它可以确保系统中一个类只产生一个实例。
2、好处
对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销。
由于new操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻GC压力,缩短GC停顿时间。
二、单例的六种写法和各自特点
饿汉、懒汉、懒汉线程安全、DCL、静态内部类、枚举
1、饿汉
public class HungurySingleton {
private static final HungurySingleton mInstance = new HungurySingleton();
private HungurySingleton(){
}
public static HungurySingleton getInstance(){
return mInstance ;
}
}
不足之处:无法对instance实例做延时加载。
2、懒汉
public class LazySingleton {
private static LazySingleton mInstance;
private LazySingleton(){
}
public static LazySingleton getInstance(){
if(mInstance == null){
mInstance = new LazySingleton();
}
return mInstance;
}
}
不足之处:在多线程并发下这样的实现是无法保证实例是唯一的。
3、懒汉线程安全
public class LazySafetySingleton {
private static LazySafetySingleton mInstance;
private LazySafetySingleton(){
}
public static synchronized LazySafetySingleton getInstance(){
if(mInstance == null){
mInstance = new LazySafetySingleton();
}
return mInstance;
}
public static LazySafetySingleton getInstance(){
synchronized (LazySafetySingleton.class){
if(mInstance == null){
mInstance = new LazySafetySingleton();
}
}
return mInstance;
}
}
不足之处:性能。使用synchronized导致性能缺陷。
4、DCL(双重检查锁机制)
public class DclSingleton {
private static volatile DclSingleton mInstance;
private DclSingleton(){
}
public static DclSingleton getInstance(){
//避免不必要的同步
if(mInstance == null){
synchronized (DclSingleton.class){
if(mInstance == null){
mInstance = new DclSingleton();
}
}
}
return mInstance;
}
}
不足之处:JVM的即时编译器中存在指令重排序的优化。
5、静态内部类
public class StaticInnerSingleton {
private StaticInnerSingleton(){
}
//静态内部类
private static class SingletonHolder{
private static final StaticInnerSingleton sInstance = new StaticInnerSingleton();
}
public static StaticInnerSingleton getInstance(){
return SingletonHolder.sInstance;
}
}
优点:JVM本身机制保证了线程安全/没有性能缺陷。
原因:static、final
6、枚举
public enum EnumSingleton {
INSTANCE;
public void doSomething(){
}
}
优点:写法简单、线程安全
三、android中的单例
1、application
public class AppContext extends Application {
private static AppContext mInstance;
public static AppContext getInstance(){
return mInstance;
}
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
}
2、单例模式引起的内存泄漏
3、eventbus的问题
网友评论