转自:http://hi.baidu.com/yshnjycwcsbchmd/item/b9629e9d6fe32c895914616b
写在前面的话:
本文介绍Singleton模式的原理及使用,主要代码使用JAVA实现.本文仅作抛砖引玉的作用,欢迎大家继续讨论。
因为Singleton(单例模式)的实现代码比较简单,因此我没有提供打包的可执行代码,不过,文中的代码直接可以编译执行。如果想自己测试Singleton,可以试着通过Object o1;Object o2的方式获取对象,然后再使用==运算符比较结果,以测试单例的状态。
如果有任何问题或建议,请联系<a href=">
##########################################################################
设计模式之Singleton模式
##########################################################################
Singleton模式
原理及JAVA实现
作者:saharabear
来自:http://saharabear.openmotel.cn
版本:V0.1
分类:设计模式
TAG:设计模式,单例模式,Design Pattern, Singleton
摘要:Singleton模式是为了实现在整个应用程序中,某一个类只能有一个实例存在。比如,在一个WEB的应用程序中,应该只存在一个链接池(内部可能包含多个链接);或者应用程序建立一个文件夹等操作的时候,只能使用单线程操作,而不允许存在两个实例操作同样的内容。
目录
1.什么是Singleton模式
2.如何实现Singleton模式
3.什么时候使用Singleton模式
4.Singleton is evil or not?
5.多线程及分布式下的Singleton
6.总结
7.关于本文
8.更新日志
9.参考文档
10.相关文档
++++++++++++++++++++++++++++++++++++++++
正文
++++++++++++++++++++++++++++++++++++++++
1.什么是Singleton模式
Singleton模式,是为了实现在一个应用程序中,某一个类只能有一个实例,也就是说只能产生一个对象。
Singleton是一种创建型模式,这意味着,如果某个类采用了Singleton模式,则在这个类被创建后,它将只可能产生一个实例供外部访问,并且会提供一个全局的访问点。
一眼看去,Singleton似乎有些像全局对象。但是实际上,全局对象和Singleton模式有本质的区别,这是因为大量使用全局对象会使得程序质量降低,而且有些编程语言根本就不支持全局变量。最重要的是传统的全局对象并不能阻止人们将一个类实例化多次。而Singleton模式则通过从根本上控制类的创建,将"保证一个类有且只有一个实例"这个任务交给了类本身。这一点是全局对象方法与Singleton模式的根本区别。
2.如何实现Singleton模式
与其他所有的模式一样,Singleton模式只是一种理念,而具体的实现则有各种不同的方法。在这里,我知道的主要有下面四种方法:
(1)使用静态方法来实现实例的创建
这里要注意使用一个private的构造方法。如果不把构造器声明为private,java的编译器会自动同步一个默认的friendly构造器. 复制内容到剪贴板 代码: public class Singleton {
(2)纯静态对象实现
/*
* private constructor to make sure nobody can create an
* object using it.
*/
private Singleton(){};
private static Singleton singleton;
/*
* Global method for instancing of the class.
*/
//make sure you use a static method
public static synchronized Singleton getInstance() {
if (singleton == null)
singleton = new Singleton();
return singleton;
}
//other method
}
产生一个纯静态的对象,然后给出一个全局的访问点供其他的对象调用
一般认为这种方式更安全一些。Jdon的板桥里人先生也是这种观点。 复制内容到剪贴板 代码:public class Singleton {
(3)设置一个静态变量作为标志位
private Singleton(){}
//use private and static keywords
private static Singleton instance = new Singleton();
//Global access
public static synchronized Singleton getInstance() {
return instance;
}
}
这种方法的原理类似于第一种方法,只不过并不是判断singleton的实例是不是存在,而是另外设置一个标志位来判断。 复制内容到剪贴板 代码:
(4)自定义Singleton生成器
public class Singleton {
static boolean instance_flag = false; // true if a instance exist
public Singleton() {
if (instance_flag)
{
//define Exception to throw
}
else{
instance_flag = true; // false if no instance exist
}
}
//other method
}
自己设计一个Singleton生成器,在一定程度上可以理解为工场模式的扩展。在这种方式下,可以转化Singleton的特点,甚至通过一定方式改变生成的Instance的数目(好像这样就不应该再叫Singleton,我见过有一种说法叫多例)。主要实现方法可以通过Hashtable或者相应的数据结构然后设置标志位和长度。
有兴趣的可以仔细查一下这方面的资料,在多核或多CPU的情况下,使用这种方式会更好一些。
3.什么时候使用Singleton模式
很多时候我们都会需要Singleton模式,最常见的比如我们希望整个应用程序中只有一个连接池实例等。但是,这种模式虽然简单,想用好却很不容易,需要考虑JVM,内存,线程,分布式等等情况。
模式本来就是一个有很大不确定性因素的东西,因此,具体什么时候使用Singleton模式,需要非常小心,同时,也没有一个完整的评价标准来确定倒底什么时候使用Singleton模式。
我个人的意见是,如果是一个容器内的应用,那么最好不要使用单例,如果需要使用,那么一定要注意分布式和多线程的问题。
另外,关于lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了,上面除了第二种方法以外,应该都属于lazy initialization。这部分的知识我理解也不够深入,不过一定要使用synchronized,如果没有使用synchronized,那么使用getInstance()是有可能得到多个Singleton实例;同时,synchronized也有可能造成浪费过多的CPU资源在一些不必要的同步上。
4.Singleton is evil or not?
很多人认为Singleton is evil。从设计上的角度来考虑,Singleton模式的引入会给程序带来一些不好的影响:
(1)结合了静态方法,由于静态方法一般由类定义,而不是接口,导致系统中其他程序过分依赖该类本身(对该类的引用被硬编码到其他类中),增加了系统的耦合度;
(2)由于静态方法和变量没有“继承”的概念,使该模式不利于扩展。
(3)由于Singleton的创建完全在本类中完成,对外界封闭,每个不同的singleton必须拥有完全独立的初始化过程,需要独立处理自己的配置。在一个大的系统中,越来越多的singleton导致系统越来越难维护。
在这里,没法确定谁对谁错,在参考文档中有相关文档,可以仔细去仔细读一读。
5.多线程及分布式下的Singleton
先说说多线程的情况下。一个单例的对象,在多线程的情况下,虽然也只有一个实例存在,但是,可能存在多个线程同时访问的情况。这时,就有可能产生混乱,以至于产生脏数据。
然后,在分布式环境下,比如使用了EJB,那么面临的环境可能是多服务器,多个JVM在运行。这时,Singleton就已经失去所有意义了,因为在不同的JVM中,都可能产生一个单例,而这多个JVM又会组成一个应用。因此,要注意这一点。
6.总结
总体上说,Singleton模式是GOF 23种设计模式中,最简单,但想用好却又非常复杂的一种模式,关于它的争论很多,不过,作为创建型的一种经典模式,只要用在最正确的地方,就可以带来很多的方便。而具体的度的把握,就需要个人的判断和理解了。