4.单元素枚举类型。使用方法类似1,很简单。但是同时也实现了Serializable接口,并且也能自动防止反序列化生成新对象。如果不考虑线程,这是比前面三中都好的方式。
// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
5.延迟创建(按需创建或称懒汉模式)
Google公司的工程师Bob Lee写的新的懒汉单例模式
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton(){
}
public Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
在加载singleton时并不加载它的内部类SingletonHolder,而在调用getInstance()时调用SingletonHolder时才加载SingletonHolder,从而调用singleton的构造函数,实例化singleton,从而达到lazy loading的效果。
6.Double-checked Locking模式在Java中是不能用的。原因有两个:
一是Java编译器处于优化的原因,生成的代码会不按照我们编写的顺序。极有可能先给instance变量赋值,然后再构造对象。这样一来在多线程环境下基于instance==null做判断就会得到错误的结果。
二是Java synchrorized保证了被保护的变量总是从内存中读取数据,而不是使用寄存器缓存的数据。但是当第一个线程已经创建好了对象,其他线程再来访问的时候,由于没有进入synchronized保护的代码,因此没有重新读取内存中的数据,因此有可能获取的是旧版本的数据。
详细理由参考下面的文章以及其参考的其他文章:
html">http://dev.firnow.com/course/3_program/java/javashl/2008414/110150.html