在我的代码中,有不少是要用到 singleton 模式的,
1, singleton 简单介绍
比如
/**
* as it hold some critical resouce in system, we should make it singleton,
* but it's not easy to do it,
*
*/
class MyUtil() {
private static instance = new MyUtil();
private MyUtil() {
// do some initial operation,
}
public static MyUtil getInstance() {
return instance;
}
}
这个是,类初始化的时候,就生成单一实例,后来就不能构造了,因为我们将 construct 方法,设为 private,
但是这种方式,有一个问题,就是我前一篇文章说的,
如果有几个 static 变量有初始值,而且在 construct 中要读 configuration value 的话,那就比较麻烦了,
或者 construct 方法中,要用到 static 变量的值,
2, 另外一种实现,
那么我们还有一个方法,lazy loading,
好像解决了,前面的问题,但是又引入了另外的问题,
先看类
/**
* as it hold some critical resouce in system, we should make it singleton,
* but it's not easy to do it,
*
*/
class MyUtil() {
private static instance;
private MyUtil() {
// do some initial operation,
}
public static MyUtil getInstance() {
if (instance == null) {
instance = new MyUtil();
}
return instance;
}
}
是否有线程安全性呢?
好像解决了上面的问题,但是,
如果两个线程同时访问呢getInstance() 那么还是有可能,创建多个 instance,
那么,我们只有在方法上加 synchronized,
public static synchronized MyUtil getInstance() {
if (instance == null) {
instance = new MyUtil();
}
return instance;
}
但是,这样有一个问题,就是,我们实际只是要初始化一次,
以后都是读,但是所有的读,之间都需要同步,
这个,效率不高,而且不适合于web 端的高并发使用,那么只能继续演化了,
我上面提到的也是一个方法。
3, 解决办法,或者建议,
static 变量都不赋值,
然后做一个统一的 static 块,在这个里面统一初始化值,并且控制顺序。
或者,如果 class 是 singleton 的话,那么那些变量,除掉 constant 的话可以用 static,
其他的,可以直接是成员变量,
不需要再声明为 static, 这样可以吗?有没有问题?
网上还有别的方法,link,
http://www.oreillynet.com/onjava/blog/2007/01/singletons_and_lazy_loading.html
http://www.jdon.com/designpatterns/singleton.htm
http://www.ibm.com/developerworks/java/library/j-dcl.html?dwzone=java