饿汉模式
线程安全,调用效率高,但是不能延时加载
public class SingletonObject1 {
private static final SingletonObject1 instance = new SingletonObject1();
private SingletonObject1() {}
public static SingletonObject1 getInstance() {
return instance;
}
}
懒汉模式
线程不安全,会产生多个实例
public class SingletonObject2 {
private static SingletonObject2 instance;
private SingletonObject2() {}
public static SingletonObject2 getInstance() {
if (null == instance) {
instance = new SingletonObject2();
}
return SingletonObject2.instance;
}
}
getInstance()方法加锁(效率低)
public class SingletonObject3 {
private static SingletonObject3 instance;
private SingletonObject3() {}
public synchronized static SingletonObject3 getInstance() {
if (null == instance) {
instance = new SingletonObject3();
}
return SingletonObject3.instance;
}
}
双重检测锁模式
由于指令重排序问题,偶尔会出现异常,比如构造方法里面有大量的操作,jvm可能不会等到所有的操作都执行完,才返回实例指针
public class SingletonObject4 {
private static SingletonObject4 instance;
private SingletonObject4() { }
public static SingletonObject4 getInstance() {
if (null == instance) {
synchronized (SingletonObject4.class) {
if (null == instance) {
instance = new SingletonObject4();
}
}
}
return SingletonObject4.instance;
}
}
5、双重检测锁模式2
通过volatile解决【4】的问题,严格要求happen before,也就是在执行【读】操作的时候必须看到完整的【写】操作
public class SingletonObject5 {
private static volatile SingletonObject5 instance;
private SingletonObject5() {}
public static SingletonObject5 getInstance() {
if (null == instance) {
synchronized (SingletonObject4.class) {
if (null == instance) {
instance = new SingletonObject5();
}
}
}
return SingletonObject5.instance;
}
}
6、静态内部类
懒加载、线程安全、效率高
public class SingletonObject6 {
private SingletonObject6() {}
private static class InstanceHolder {
private final static SingletonObject6 instance = new SingletonObject6();
}
public static SingletonObject6 getInstance() {
return InstanceHolder.instance;
}
}
7、枚举
枚举是线程安全的,而且只会被装载一次
public class SingletonObject7 {
private SingletonObject7() {}
private enum Singleton {
INSTANCE;
private final SingletonObject7 instance;
Singleton() {
instance = new SingletonObject7();
}
public SingletonObject7 getInstance() {
return instance;
}
}
public static SingletonObject7 getInstance() {
return Singleton.INSTANCE.getInstance();
}