所谓“懒汉式”与“饿汉式”的区别,是在与建立单例对象的时间的不同。
“懒汉式”是在你真正用到的时候才去建这个单例对象:
比如:有个单例对象
public class Singleton{
private Singleton(){}
private static Singleton singleton = null; //不建立对象
public static synchronized Singleton getInstance(){
if(singleton == null) { //先判断是否为空
singleton = new Singleton (); //懒汉式做法
}
return singleton ;
}
}
“饿汉式”是在不管你用的用不上,一开始就建立这个单例对象:比如:有个单例对象
public class Singleton{
public Singleton(){}
private static Singleton singleton = new Singleton(); //建立对象
public static Singleton getInstance(){
return singleton ;//直接返回单例对象 }}
它有以下几个要素:
· 私有的构造方法
· 指向自己实例的私有静态引用
· 以自己实例为返回值的静态的公有的方法
废话少说,先列出代码(java)
[java] view plain copy
1. class Instance{}
2. //懒汉式
3. class LSingle{
4. private static Instance _instance = null;
5. private LSingle(){}
6.
7. public static Instance getInstance(){
8. if(_instance==null){
9. synchronized(LSingle.class){
10. _instance = new Instance();
11. }
12. }
13. return _instance;
14. }
15. }
16. //饿汉式
17. class ESingle{
18. private static Instance _instance = new Instance();
19.
20. private ESingle(){}
21.
22. public static Instance getInstance(){
23. return _instance;
24. }
25. }
单件模式用途:
单件模式属于工厂模式的特例,只是它不需要输入参数并且始终返回同一对象的引用。
单件模式能够保证某一类型对象在系统中的唯一性,即某类在系统中只有一个实例。它的用途十分广泛,打个比方,我们开发了一个简单的留言板,用户的每一次留言都要将留言信息写入到数据库中,最直观的方法是没次写入都建立一个数据库的链接。这是个简单的方法,在不考虑并发的时候这也是个不错的选择。但实际上,一个网站是并发的,并且有可能是存在大量并发操作的。如果我们对每次写入都创建一个数据库连接,那么很容易的系统会出现瓶颈,系统的精力将会很多的放在维护链接上而非直接查询操作上。这显然是不可取的。
如果我们能够保证系统中自始至终只有唯一一个数据库连接对象,显然我们会节省很多内存开销和cpu利用率。这就是单件模式的用途。当然单件模式不仅仅只用于这样的情况。在《设计模式:可复用面向对象软件的基础》一书中对单件模式的适用性有如下描述:
1、当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
2、当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
关于Instance类应该如何设计:
如上面叙述,我们保证单件模式类是我们取得单件实例的唯一访问点。那么我们应该保证在程序中尽量避免允许创建Instance实例。
通过将构造函数声明为private可以防止程序员通过new关键字调用构造上函数创建对象。并且在Instance类中创建getXXX()方法调用构造函数并返回具体Instance实例。具体代码如下:
[java] view plain copy
1. class Instance{
2. private Instance(){}
3.
4. public static Instance getSelf(){
5. return new Instance();
6. }
7. }
8. //懒汉式
9. class LSingle{
10. private static Instance _instance = null;
11. private LSingle(){}
12.
13. public static Instance getInstance(){
14. if(_instance==null){
15. synchronized(LSingle.class){
16. _instance = Instance.getSelf();
17. }
18. }
19. return _instance;
20. }
21. }
22. //饿汉式
23. class ESingle{
24. private static Instance _instance = Instance.getSelf();
25.
26. private ESingle(){}
27.
28. public static Instance getInstance(){
29. return _instance;
30. }
31. }
下面对单件模式的懒汉式与饿汉式进行简单介绍:
1、饿汉式:在程序启动或单件模式类被加载的时候,单件模式实例就已经被创建。
2、懒汉式:当程序第一次访问单件模式实例时才进行创建。
如何选择:如果单件模式实例在系统中经常会被用到,饿汉式是一个不错的选择。
反之如果单件模式在系统中会很少用到或者几乎不会用到,那么懒汉式是一个不错的选择。