 |
| 再论Singleton模式 |
|
sheldonsun 原创 更新:2006-10-30 14:06:59 版本: 1.0
|
|
Singleton模式可能是应用最广泛的模式之一了, 但有些错误的应用。
Singleton的实现: 有两种方式, 如下: 1. class Test { public static final Test instance = new Test(); private Test() {} }
2. class Test { private static final Test instance = new Test(); private Test() {} public static Test getInstance() { return instance; } }
这两种方法都要求构造器是私有的, 这样就可以防止该类外的对象创建新的TEST对象。
但相对而言, 推荐使用第二种方法, 因为其更具有灵活性,当我们改变创建对象的方式的时候, 不需要改动客户代码。 第一种方法较第二种有一点完全可以忽略不计的效率的提高。
但应避免如下代码实现Singleton:
class Test { private static Test singleton = null; private Test() {} public Test getSingleton() { if(singleton == null) { singleton = new Test(); } return singleton; } }
因为严格上讲, 这并不能完全实现Singleton模式,而且会导致程序出错, 这同著名的线程问题--DCL实效的原理是完全一样的:JVM创建对象的过程可以分为几个步骤:创建空间, 把所有的变量赋值位默认值, 初始化。。。 当有两个线程A和B同事进入该方法, A先执行, A创建Test实例的空间, 这时,因为CPU的指令流机制,时间片段正好轮到B线程, 这时B判断singleton是否为NULL, 因为A已经为Test的实例分配了空间, 所以JVM认为实例已经创建了, B继续执行, 更糟糕的是B调用了singleton, 这时因为他并没有初始化完全, 所以抛出NullPointerException, 太糟糕了!
|
|
|
评论人:82529gfl
|
发表时间: Wed Nov 01 11:33:10 CST 2006
|
不同意作者的观点! class Test { private static Test singleton = null; private Test() {} public Test getSingleton() { if(singleton == null) { singleton = new Test(); } return singleton; } } 这种应该称为Singleton中的惰性初始化,虽然对Multi-Thread Program有可能出错,可能出现多个实例,我们可以这样解决,加上同步: class Test { private static Test singleton = null; private Test() {} public Test synchronized getSingleton() { if(singleton == null) { singleton = new Test(); } return singleton; } }
|
|
|
评论人:MiMiEye
|
发表时间: Wed Nov 01 19:25:39 CST 2006
|
是的,同意我楼上兄弟的观点 而且视应用场合来判断那种方式更合理些.(主要是一种是只要类加载器一加载类时,自己的实例是否被创建的区别)
|
|
|
评论人:82529gfl
|
发表时间: Thu Nov 02 13:28:43 CST 2006
|
![[:D]](/faces/28.gif) JVM的内存是有限的,并且我们的程序也要给用户友好的感觉。 其实初始化也是一个很矛盾的话题,我们当然希望能在程序启动时尽可能多的初始化或者取得我们需要的数据,但是这样做的后果就是可能OutofMemory或者是我们的启动速度异常的慢。我们只能做到必要的去初始化一些数据,其他的数据以后用到的时候再去取得或者去初始化,这就使用到了惰性初始化。
|
|
|
评论人:hyhongyong
|
发表时间: Fri Nov 03 10:11:34 CST 2006
|
文章好,评论更好!!![[good]](/faces/76.gif)
|
|
|
评论人:oboaix
|
发表时间: Fri Nov 03 12:32:21 CST 2006
|
学习中,
|
|
|
评论人:lsg_zju
|
发表时间: Sun Nov 05 13:23:44 CST 2006
|
作者说的最后一个不好的方法,引用如下: class Test { private static Test singleton = null; private Test() {} public Test getSingleton() { if(singleton == null) { singleton = new Test(); } return singleton; } } 那么如何获得Test类的实例呢?
构造方法是私有的,getSingleton()方法不是静态的 应该在作者的第二种实现的getSingleton前加上synchronized吧?
“再论Singleton模式”第一论我并没有看过 一点拙见,请指教
|
|
|
评论人:lsg_zju
|
发表时间: Sun Nov 05 13:28:31 CST 2006
|
应该把最后一个方法加上静态的和synchronized 前面说错了 刚发上去看不到 所以先留下这句话 观望ing
|
|
|
评论人:jinyi1161
|
发表时间: Mon Nov 06 09:58:02 CST 2006
|
|
|
|
评论人:zhyiwww
|
发表时间: Mon Nov 06 10:40:37 CST 2006
|
把上面的那段程序改成下面的代码: class Test { private static Test singleton = null; private Test() { if(singleton == null) { singleton = new Test(); } } public Test getSingleton() {
return singleton; } } 不知道这样实现可以吗?
|
|
|
评论人:wangminbyxy
|
发表时间: Tue Nov 21 21:32:22 CST 2006
|
|
同意二楼初始化,惰性初始化在某种意义上是比较好的,加上同步,就可以了
|
|
|
评论人:pdw2009
|
发表时间: Thu Nov 30 23:44:56 CST 2006
|
|
应该看看《JAVA与模式》这本书,这有详细的说明
|
|
|
评论人:mrou2001
|
发表时间: Thu Dec 07 14:31:02 CST 2006
|
加油啊,支持
|
|
|
评论人:wangdi
|
发表时间: Mon Jan 08 12:07:39 CST 2007
|
-
- public class SingletonDemo {
- //第一种方式
- private static SingletonDemo instance = new SingletonDemo();
- private SingletonDemo(){}
- public static SingletonDemo getInstance(){
- return instance;
- }
- //第二种方式
- // private static SingletonDemo instance = null;
- // public static synchronized SingletonDemo getInstance() {
- // if(instance == null){
- // instance = new SingletonDemo();
- // }
- // return instance;
- // }
- }
|
|
|
评论人:maojinyw
|
发表时间: Tue Jun 03 14:35:28 CST 2008
|
学习了...
|
|
|
|
|
 |