单例模式的特征
单例模式六种写法
public class Singleton {
private static Singleton sInstance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return sInstance;
}
}
public class Singleton {
private static Singleton sInstance = null;
private Singleton() {
}
public static Singleton getInstance() {
if (sInstance == null) {
sInstance = new Singleton();
}
return sInstance;
}
}
public class Singleton {
private static Singleton sInstance = null;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (sInstance == null) {
sInstance = new Singleton();
}
return sInstance;
}
}
public class Singleton {
private static volatile Singleton sInstance = null;
private Singleton() {
}
public static Singleton getInstance() {
if (sInstance == null) {
synchronized (Singleton.class) {
if (sInstance == null) {
sInstance = new Singleton();
}
}
}
return sInstance;
}
}
public class Singleton {
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
}
public enum Singleton {
INSTANCE;
public static Singleton getInstance() {
return INSTANCE;
}
}
public class Singleton {
private static final AtomicReference<Singleton> INSTANCE = new AtomicReference<>();
public Singleton getInstance() {
for (; ; ) {
Singleton singleton = INSTANCE.get();
if (singleton != null) {
return singleton;
}
singleton = new Singleton();
if (INSTANCE.compareAndSet(null, singleton)) {
return singleton;
}
}
}
}
单例模式注意点
- 反射可能会破坏单例模式,通过反射可以强制调用构造函数,生成对象实例,这里构造函数内部可以加入判断,如果对象实例已存在,则抛出异常,禁止再次调用。
- 反序列化可能会破坏单例,反序列还的过程中,会重新生成对象,这里可以在单例类中定义一个readResolve()方法,内部返回已创建的实例,使其在反序列化的过程中调用该方法,仍然返回之前的实例。
- 克隆可能会破坏单例模式,通过重写clone方法,返回已创建的实例