今天在《Effective Java》-考虑用静态工厂方法代替构造器中提到单例模式
private static SystemManager sm = new SystemManager();
private SystemManager(){}
public static SystemManager getInstance(){
return sm;
}
后来翻看《Java与模式》,书中单例模式分两种:
饿汉式:类被加载时,静态变量会被初始化,此时类的私用构造器会被调用,单例的唯一实例即被创建出来,即使该类还未被调用
public class EagerSingleton {
private static final EagerSingleton EAGER_SINGLETON = new EagerSingleton();
private EagerSingleton(){
}
public static EagerSingleton getInstance(){
return EAGER_SINGLETON;
}
}
懒汉式:类被加载时,静态变量会被初始化,但并不会调用构造器实例化对象,只有在静态工厂方法被调用时采用判断是否已经实例化,若未实例化才会进行实例化
public class LazySingleton {
private static LazySingleton lazySingleton = null;
private LazySingleton(){
}
public synchronized static LazySingleton getInstance(){
if (lazySingleton == null) {
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
添加synchronized 关键字是在多线程环境下,防止重复进入if判断实例化对象。
这里有两个疑问:
1.静态成员变量是否需要final修饰?
《Java与模式》书中饿汉模式是修饰的,懒汉模式未修饰。
网上其他博客上有人使用final修饰,也有人没有使用final修饰。
2.懒汉式是否可以使用双重检测?
《Java与模式》书中说Java语言中不可以使用双重检测
文中提到文献[BLOCH01]中指出:一般而言,双重检查成立对Java语言来说是不成立的
一般情况下,使用饿汉式单例模式或者对整个静态工厂方法同步化的懒汉单例模式足以解决实际设计工作中遇到的问题。
但是我在http://www.chenyudong.com/archives/java-singleton.html这篇博文中看到其使用了双重检测
这篇博文写的是通过枚举实现单例:
http://coolxing.iteye.com/blog/1446648