定义
确保某一个类只有一个实例,而且自行实例化并向整个系统提供。
实现方式
1 饿汉式
// 线程安全,因为JVM只会实例化1次
public class Singleton {
Singleton sInstance = new Signleton();
public static Singleton getInstance() {
return sInstance;
}
}
2 懒汉式
// 线程不安全,因为多线程时,并发可能会造成在 if 判断的时候多次实例化
public class Singleton {
Singleton sInstance = null;
public static Singleton getInstance() {
if (null == sInstance) {
sInstance = new Singleton();
}
return sInstance;
}
}
3 同步锁
// 线程安全。饿汉式的第一种改进。但会造成每一次都会消耗锁资源
public class Singleton {
Singleton sInstance = null;
public static synchronized Singleton getInstance() {
if (null == sIntance) {
sInstance = new Singleton();
}
return sInstance;
}
}
4 双重校验锁 🌟
// 线程安全。懒汉式的第二种改进。不会造成重复消耗锁资源,适应绝大部分情况。
// 但极小几率会造成DCL(Double Check Locked) 异常。可以通过增加 volatile 关键字来解决
public class Singleton {
Singleton sInstance = null;
public static Singleton getInstance() {
if (null == sInstance) {
synchronized(Singleton.class) {
if (null == sInstance) {
sInstance = new Singleton();
}
}
}
return sInstance;
}
}
5 静态内部类 🌟
// 线程安全。不会发生DCL异常,推荐使用。
public class Singleton {
public static Singleton getInstance() {
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final Singleton sInstance = new Singleton();
}
}
6 枚举
// 线程安全,写法简单,推荐使用。
public enum Singleton {
INSTANCE; // 这就是 Singleton 的一个实例
}
7 容器实现(Map)
// 线程安全。单例管理类,可以单例化多个类
// Android 系统中 context.getSystemService(xxxx); 就是以此方式为基础实现单例
public class SingletonManger {
private static Map<String, Object> instanceMap = new HashMap<String, Object>();
private SingletonManager() { }
// 注册实例
public static void registerService(String key, Object instance) {
if (!instanceMap.contains(key)) {
instanceMap.put(key, instance);
}
}
// 获取实例
public static Object getService(String key) {
return instanceMap.get(key);
}
}
网友评论