单例模式
2019-10-09 本文已影响0人
spraysss
1. 饿汉模式
这种设计存在的问题是无法懒加载
public class Singleton1 {
private Singleton1(){
}
public static final Singleton1 INSTANCE=new Singleton1();
public static Singleton1 getInstance(){
return INSTANCE;
}
}
2. 非线程安全懒汉模式
这种设计虽然是懒加载但是在多线程环境下会有线程安全的问题
public class Singleton2 {
private Singleton2() {
}
private static Singleton2 INSTANCE;
public static Singleton2 getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton2();
}
return INSTANCE;
}
}
3. double check synchronized
最小化锁粒度同步,由于jmv 编译器等优化原因会导致空指针异常
public class Singleton3 {
private Singleton3() {
}
private static Singleton3 INSTANCE;
public static Singleton3 getInstance() {
if (null == INSTANCE) {
synchronized (Singleton3.class) {
if (null == INSTANCE) {
INSTANCE = new Singleton3();
}
}
}
return INSTANCE;
}
}
4. volatile + double check
使用 volatile + double check保证了可见行,解决了3中有可能出现等空指针异常
public class Singleton4 {
private Singleton4() {
}
private static volatile Singleton4 INSTANCE;
public static Singleton4 getInstance() {
if (null == INSTANCE) {
synchronized (Singleton4.class) {
if (null == INSTANCE) {
INSTANCE = new Singleton4();
}
}
}
return INSTANCE;
}
}
5. 使用静态内部类
巧妙的使用jvm类加载特性,完成使用时一次加载,并且线程安全
public class Singleton5 {
private Singleton5() {
}
private static class Singleton5Holder {
private static final Singleton5 INSTANCE = new Singleton5();
}
public static Singleton5 getInstance() {
return Singleton5Holder.INSTANCE;
}
}
6. 使用枚举
利用enum在使用时只初始化一次的特性
public class Singleton6 {
private Singleton6() {
}
private enum SingletonEnum {
INSTANCE;
private Singleton6 instance;
SingletonEnum() {
instance = new Singleton6();
}
private Singleton6 getInstance() {
return instance;
}
}
public static Singleton6 getInstance() {
return SingletonEnum.INSTANCE.getInstance();
}
}