分享

GoF设计模式之五 Singleton- -

 wtf_soft 2005-07-22

 

                                      

    A5) Singleton(单态模式)
    定义:保证一个类只存在一个实例,并提供一个全局访问的指针。
    这个也是非常常见的模式,可以说很难在一个项目中不使用这个模式。对于全局变量来说,唯一和同步是至关重要的,一般来说以下面的这种方式来实现。
    public class Singleton {
        private Singleton(){}
        private static Singleton instance = new Singleton();
        public static Singleton getInstance() {
        return instance;
        }
    }

    第一行必须用private的构造函数,这样才能防止别的class生成Singleton的实例,而第二行的static定义让变量instance在所有Singleton实例中是唯一的(当然,这个例子实际上只有一个实例),那么每次通过getInstance()得到的变量instance就是Singleton的唯一实例。还有一种方法,如下:
    public class Singleton {
        private Singleton(){}
        private static Singleton instance = null;
        public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
        }
    }

    这种方法叫做lazy initialization技术,不过关于这种技术的争议很多,牵涉到double-checked locking(DCL)问题。关于这个问题,稍微解释一下,具体我也不是太明确,有兴趣可以另外研究。编译器在编译执行命令的时候,由于会使用代码优化,在synchronized段中的代码就有可能会被提前执行以加快代码效率。这个时候,也就是instance = new Singleton();这部分语句可能被预先优化执行,那么它的唯一性也就不能保证了。虽然还只是在理论上推论这个结果,并没有用事实来验证这一说法,现在也没发现这个方法造成的不良后果,但是,我觉得还是推荐第一种方法,简单而容易理解。
    注:感谢rwyx的指点,因为以前理解有偏差,所以将上面部分删除后重新改写。
    这种方法叫做lazy initialization技术,使用了synchronized关键字,不过这种方法的系统开销比较大,所以还是推荐地一种方法,简单而且效率高,最好在定义时追加final关键字。
    关于Singleton,在C++/C#等语言中会用到一种叫做double-checked的技术,目的是为了解决lazy initializtion技术中同步代码效率低的问题。具体实现如下:
    public static Singleton getInstance() { 
        if (instance == null) { 
            synchronized { 
                if (instance == null) {instance = new Singleton();} 
            } 
        } 
        return instance; 
    } 
    即在同步前做一次判断,这样只有第一次时会进入同步段,这样效率也很高。不过这种方法在java中却是错误的。因为java语言规范和C++/C# 等不同,是一个非常灵活的规范。java编译器可以自由地重排变量的初始化和访问顺序,以提高运行时效率;同时java中的变量访问是可以被自动缓存到寄存器的,这也导致潜在的JIT 编译器相关的依赖性错误。每个编译器可能有不同的实现方法,同样的代码在不同编译器和执行环境下可能有不同的表现。解决的办法有很多,使用线程局部存储(ThreadLocal)来保存instance变量,或者使用volatile关键字来定义instance,强制java编译器不进行优化。DCL参考资料: http://www./User8/flier_lu/blog/1620823.html


   参考:
1、 http://www./designpatterns/singleton.htm(中文、java实例)
2、 http://www./Patterns/PatternSingleton.aspx(英文、C#实例、UML)
3、 http://www./tech/DesignPattern/Singleton.html(日文、java实例、UML)推荐

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多