一、懒汉模式:
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
可以延迟加载,但线程不安全。
二、懒汉模式变种:
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
跟一相比,使用了synchronized关键字,既可以延迟加载,又线程安全,但是执行效率低。
三、恶汉模式:
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
基于classloader机制,在类装载时就实例化,可以避免线程安全问题,但是没有延迟加载。
四、恶汉模式变种:
public class Singleton {
private Singleton instance = null;
static {
instance = new Singleton();
}
private Singleton (){}
public static Singleton getInstance() {
return this.instance;
}
}
原理同三,只是把实例化操作放到了静态块里,优缺点同三。
五、双重校验锁:
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
这实际上是懒汉模式的优化版,拥有线程安全、高效率以及延迟加载等特性。但是这种方式需要jdk1.5以上,且在一些平台和编译器下有错。
六、静态内部类:
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
这实际上是恶汉模式的优化版,在类被装载时,静态内部类并没有被实例化,只有getInstance()时才
会装载
SingletonHolder
类,静态内部类方式也能很好地,实现线程安全、高效率和延迟加载特性。
七、枚举:
一个例子介绍。
public enum SingletonEnum
{
INSTANCE01,INSTANCE02;
private String name;
publicString getName()
{
returnname;
}
publicvoid setName(String name)
{
this.name = name;
}
}
测试
public class Test
{
public static void main(String[] args)
{
SingletonEnum instance01=SingletonEnum.INSTANCE01;
instance01.setName("terje");
System.out.println(instance01.getName());
SingletonEnum instance02=SingletonEnum.INSTANCE01;
System.out.println(instance02.getName());
SingletonEnum instance03=SingletonEnum.INSTANCE02;
instance03.setName("liu");
System.out.println(instance03.getName());
SingletonEnum instance04=SingletonEnum.INSTANCE02;
instance04.setName("liu");
System.out.println(instance04.getName());
}
}
这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象,可谓是很坚强的壁垒;但是这种方式也需要jdk1.5以上版本。