第一种:非延迟加载单例类(饿汉式)
package test;
public class Singleton {
private Singleton() {
}
private static final Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
第二种:同步延迟加载(懒汉式)
package test;
public class Singleton {
private static Singleton instance = null;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
饿汉式是在类装载时直接得到该类的实例,而懒汉式在等到真正使用的时候调用工厂方法进行创建实例。因此,前者速度快,后者速度慢。但后者可以加载其他的类,(也就是动态扩展)灵活性高。
第三种:双重检测同步延迟加载(JDK5.0以上版本支持)
package test;
public class Singleton {
private volatile static Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
双重检测同步延迟加载是为了解决非延迟加载方式过多的同步产生瓶颈问题。
第四种:使用ThreadLocal修复双重检测
package test;
public class Singleton {
private static final ThreadLocal perThreadInstance = new ThreadLocal();
private static Singleton singleton;
private Singleton() {
}
public static Singleton getInstance() {
if (perThreadInstance.get() == null) {
createInstance();
}
return singleton;
}
private static final void createInstance() {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
perThreadInstance.set(perThreadInstance);
}
}
第五种:使用内部类实现延迟加载
package test;
public class Singleton {
private Singleton() {
}
public static class Holder {
static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return Holder.instance;
}
}
事实上第三种双重检测同步延迟加载方式已经是安全的了。