定义:
确保某个类只有一个实例,并且自行实例化和向整个系统提供这个实例。使用场景:
避免产生多个对象消耗过多的资源,或者某种类型的对象有且只能有一个。
例如创建一个对象要消耗过多资源,如要访问IO和数据库等资源,此时就要考虑单例模式。实现方式:
a. 饿汉模式
在类初始化的时候自行实例化
public class Singleton {
private static Singleton sInstance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return sInstance;
}
}
b. 懒汉模式
声明一个静态对象,并且在用户第一次调用getInstance时进行初始化
public class Singleton {
private static Singleton sInstance;
private Singleton() {
}
public static Singleton getInstance() {
if(null == sInstance) {
sInstance = new Singleton();
}
return sInstance;
}
}
c. Double Check Lock 模式(DCL)
懒汉模式的改进:
既能在需要时才初始化实例,又能保证线程安全且单例对象初始化后调用getInstance不进行同步锁
代码如下:
public class Singleton {
private static Singleton sInstance;
private Singleton() {
}
public static Singleton getInstance() {
if(null == sInstance) {
synchronized (Singleton.class) {
sInstance = new Singleton();
}
}
return sInstance;
}
}
d. 静态内部类模式
第一次加载类时不会初始化instance,只有在第一次调用Singleton的getInstance方法才会导致instance被初始化。第一次调用geiInstance方法会导致虚拟机加载SingletonHolder类这种方法不禁能保证线程安全,也能保证单例对象的唯一性,同时也延迟了单例的实例化。推荐使用
public class Singleton {
private Singleton() {
}
public static Singleton getInstance() {
return Holder.sInstance;
}
private static class Holder {
private static Singleton sInstance = new Singleton();
}
}
e. 容器实现模式
在程序的初始,将多种单例类型添加到一个管理类中,使用时用key获取对象。该种方式让统一管理和获取多种类型的单例,可以降低使用成本,同时隐藏了具体实现,降低耦合度。
public class SingletonManager {
private static Map<String, Object> instanceMap = new HashMap<>();
private SingletonManager() {
}
public void register(String key, Object object) {
if(!instanceMap.containsKey(key)) {
instanceMap.put(key, object);
}
}
public Object getInstance(String key) {
return instanceMap.get(key);
}
}