饿汉模式
public class Singleton {
// 因实例跟随类加载而生成,故称饿汉模式
private static Singleton s = new Singleton();
private Singleton(){}
public static getInstance(){
return s;
}
}
懒汉模式
public class Singleton {
private static Singleton s;
private Singleton(){}
// 因在使用时才创建,故称懒汉模式
public static getInstance(){
if (s == null) {
s = new Singleton();
}
return s;
}
}
以上两种均不是线程安全的
DCL
public class Singleton {
// 注意加了volatile
private volatile static Singleton s;
private Singleton(){}
// 注意加锁前后要2次判空
public static Singleton getInstance(){
if (s == null) {
synchronized (Singleton.class) {
if (s == null) {
s = new Singleton();
}
}
}
return s;
}
}
《Android源码设计模式》中说DCL锁机制有可能失效,但没说为什么
静态内部类实现
public class Singleton {
private static Singleton getInstance() {
return SingletonHolder.s;
}
private static class SingletonHolder {
private static final Singleton s = new Singleton();
}
}
这种方式既保证线程安全,也实现懒加载,是推荐使用的方式
以上4种均不能防止反序列化创建另一个对象。如果要实现反序列化也不能创建另一个对象,要加入下面的代码
private Object readResolve() throws ObjectStreamException {
return s;
}
或使用下面这种方式
枚举实现
public enum Singleton {
INSTANCE;
}
枚举实现也是线程安全的