单例模式的五种实现方式
三个饿汉式和两个懒汉式
三个饿汉式
1、通过枚举的方式实现饿汉式
public enum Single {
INSTANCE;
}
可以直接通过Single.INSTANCE的方式对单例进行调用,通过public修饰属性,公开访问。
2、通过类名.属性的方式进行单例调用
public class Single {
public static final Single INSTANCE = new Single();
private Single(){};
}
同①中的枚举获取方式类似,可通过Single.INSTANCE方式获取单例变量INSTANCE
3、通过getInstance方法获取单例
public class Single {
private static final Single INSTANCE = new Single();
private Single (){};
public static Single getInstance() {
return INSTANCE;
}
}
两个懒汉式
1、通过内部类的方式实现懒汉式单例模式,因为内部类不会跟随着外部类同时加载,所以可以通过内部类的方式实现懒汉式单例模式
public class Single{
private Single(){};
private static class Inner {
static final Single INSTANCE = new Single();
}
public static Single getInstance() {
Inner.INSTANCE;
}
}
2、通过volatile+双重锁同步锁实现多线程懒汉式加载,如果不使用volatile修饰实例属性,在多线程中如果发生指令重排序可能发生空指针问题
public class Single{
private Single(){};
private static volatile Single INSTANCE = null;
public static Single getInstance() {
if(INSTANCE == null) {
synchronized(Single.class) {
if(INSTANCE == null) {
INSTANCE = new Single();
}
}
}
}
}
以上五种单例实现方式都是线程安全的,只是各有不同,看你是需要时间还是空间,如果需要时间可直接使用饿汉式,如果需要空间可以直接使用懒汉式。以上仅供参考,如有错误,望各位能给出正确解释