设计模式-单例模式
2019-06-24 / 2 min read
Ensure a class has only one instance, and provide a global point of access to it.(确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。)
类图

饿汉模式
public class Singleton {
private static final Singleton SINGLETON = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return SINGLETON;
}
}
懒汉模式
public class SingletonLay {
private static SingletonLay singletonLay = null;
private SingletonLay() {
}
public static SingletonLay getSingletonLay() {
if (singletonLay == null) {
synchronized (SingletonLay.class) {
if (singletonLay == null) {
singletonLay = new SingletonLay();
}
}
}
return singletonLay;
}
}
隐患
上述写法看似解决了问题,但是有个很大的隐患。实例化对象的那行代码(标记为error的那行),实际上可以分解成以下三个步骤:
-
分配内存空间
-
初始化对象
-
将对象指向刚分配的内存空间
但是有些编译器为了性能的原因,可能会将第二步和第三步进行重排序,顺序就成了: -
分配内存空间
-
将对象指向刚分配的内存空间
-
初始化对象
正确的双重检查锁
public class SingletonLay {
private static volilate SingletonLay singletonLay = null;
private SingletonLay() {
}
public static SingletonLay getSingletonLay() {
if (singletonLay == null) {
synchronized (SingletonLay.class) {
if (singletonLay == null) {
singletonLay = new SingletonLay();
}
}
}
return singletonLay;
}
}
Enum 方式
class Resource{
}
public enum Singleton {
INSTANCE;
private Resource instance;
Singleton() {
instance = new Resource();
}
public Resource getInstance() {
return instance;
}
}