1. 单例概念
单例模式是一种对象创建模式,它用于产生一个对象的具体实例,它可以确保系统中一个类只产生一个实例。
2. 好处
对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销。
由于new操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻GC压力,缩短GC停顿时间。
3. 单例的写法
饿汉、懒汉、懒汉线程安全、DCL、静态内部类、枚举
3.1 饿汉
public class EagerSingleton {
private final static EagerSingleton mEagerSingleton = new EagerSingleton();
private EagerSingleton() {
System.out.println("create singleton");
}
public static EagerSingleton getEagerSingleton() {
return mEagerSingleton;
}
}
无法对单例实例延时加载。
3.2 懒汉
public class LazySingleton {
private static LazySingleton mLazySingleton = null;
private LazySingleton() {
}
public static LazySingleton getLazySingleton() {
if (mLazySingleton == null) {
mLazySingleton = new LazySingleton();
return mLazySingleton;
}
return mLazySingleton;
}
}
在多线程并发下无法保证实例唯一。
3.3 懒汉线程安全
public class LazySaftySingleton {
private static LazySaftySingleton mLazySaftySingleton = null;
private LazySaftySingleton() {
}
public static synchronized LazySaftySingleton getLazySingleton() {
if (mLazySaftySingleton == null) {
mLazySaftySingleton = new LazySaftySingleton();
return mLazySaftySingleton;
}
return mLazySaftySingleton;
}
}
性能不足
3.4 DCL
public class DCLSingleton {
// jvm指令重排序优化,使用volatile禁止jvm指令重排序优化
private static volatile DCLSingleton mInstance = null;
private DCLSingleton() {
}
public static DCLSingleton getInstance() {
// 避免不必要的同步
if (mInstance == null) {
// 同步方法
synchronized (DCLSingleton.class) {
// 在第一次时同步初始化
if (mInstance == null) {
mInstance = new DCLSingleton();
}
}
}
return mInstance;
}
}
jvm的即时编译器中存在指令重排序的优化。
3.5 静态内部类
static 初始化操作保证数据在内存中是唯一的,final无法在初始化后有赋值操作,所以也是线程安全的。
public class StaticInnerSingleton {
private StaticInnerSingleton() {
}
public static StaticInnerSingleton getInstance() {
return SingletonHolder.mInstance;
}
private static class SingletonHolder {
private static final StaticInnerSingleton mInstance = new StaticInnerSingleton();
}
}
jvm本身机制保证了线程安全,没有性能缺陷。
3.6 枚举
class Resource {
}
public enum EnumSingleton {
INSTANCE;
private Resource instance;
private EnumSingleton() {
instance = new Resource();
}
public Resource getInstance() {
return instance;
}
}
写法简单,线程安全。
4. android中的单例模式
application,是android系统为程序创建的唯一实例,采用的是单例模式。可以在Application中存放全局的静态变量属性,方便各个工具类的调用。