饿汉模式
类加载时创建对象【常量】
class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {
}
public static EagerSingleton getInstance() {
return instance;
}
}
懒汉模式
延迟加载;
假如在某一瞬间”线程A”和”线程B”都在调用getInstance()方法,此时instance对象为null值,均能通过instance == null的判断。
由于实现了synchronized加锁机制,”线程A”进入synchronized锁定的代码中执行实例创建代码,”线程B”处于排队等待状态,必须等待”线程A”执行完毕后才可以进入synchronized锁定代码。
但当”线程A”执行完毕时,”线程B”并不知道实例已经创建,将继续创建新的实例,导致产生多个单例对象,违背单例模式的设计思想,因此需要进行进一步改进,在synchronized中再进行一次instance == null判断,这种方式称为 双重检查锁定(Double-Check Locking)。
class LazySingleton {
private volatile static LazySingleton instance = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
//第一重判断
if (instance == null) {
//锁定代码块
synchronized (LazySingleton.class) {
//第二重判断
if (instance == null) {
instance = new LazySingleton(); //创建单例实例
}
}
}
return instance;
}
}
IoDH
延迟加载且不需要进行线程安全控制
//Initialization on Demand Holder
class Singleton {
private Singleton() {
}
private static class HolderClass {
private final static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return HolderClass.instance;
}
public static void main(String args[]) {
Singleton s1, s2;
s1 = Singleton.getInstance();
s2 = Singleton.getInstance();
System.out.println(s1 == s2);
}
}