singleton 模式使用问题

来源:互联网 发布:剧本统计软件 编辑:程序博客网 时间:2024/05/16 13:00

在我的代码中,有不少是要用到 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