设计模式学习笔记:单例(singleton)模式

Written on July 28, 2008 – 4:47 pm | by 陈炬 | 63 views

From Wikipedia: the singleton pattern is a design pattern that is used to restrict instantiation of a class to one object.

文中关于设计模式的描述与实现很可能跟Java语言特性有关。

单例模式是很简单的一种设计模式,它的主要目的是保证在程序运行过程中,某个特定的类只存在一个实例。很多时候,我们采用将类的成员和方法静态化也可以实现这样的需求。有的时候,这样做是无伤大雅的,但是有的时候采用静态方法来替代单利模式是不恰当的。且这还会跟具体的语言特性相关。

Java采用构造器来创建一个新的实例,因此只需要将构造器设为私有,便可以阻止其他类不负责任的随意构造实例,同时,我们还需要有一个静态的方法来返回或者构造一个实例。简单代码如下:

1
2
3
4
5
6
7
8
9
10
11
public class Singleton{
        private static Singleton foo;
        private Singleton(){}
        /*
         a lot of other codes here
        */
        public Singleton getInstance(){
                 if(foo==null) foo=new Singleton();
                 return foo;
        }
}

可以看到,单例模式无论从概念上还是实现上都是比较简单的。但是,如果我们的代码运行在多线程环境中,会发生什么情况呢?如果运气足够的不好,方法getInstance()可能同时由几个线程在调用,而此时恰好foo还是null,那么就会创建多个实例。我们的getInstance方法不是线程安全的,如何解决呢?

方法1:getInstance()方法仅仅在实例还没有被创建的时候才会出现线程不安全的问题,如果我们非常早的就创建了实例,那么就没有这个问题了,比如这样:

1
  private static Singleton foo=new Singleton();

因此,解决单例模式线程安全问题一种方法就是非常早的实例化

方法2:利用Java的同步机制,对getInstance()方法加锁,可以彻底避免线程安全问题,比如:

1
  synchronized getInstance(){..

,这种方法能解决问题,但是性能相当底下,不推荐使用。

方法3:同方法2一样的思路,只是不是对方法本身加锁,而只是对方法内部其中的一块加锁。这种特性只有Java5.0以后才支持。真正造成线程安全问题的是getInstance中创建实例的部分,只需要同步这部分即可。

1
2
3
4
5
6
7
8
  public Singleton getInstance(){
           if(foo==null) {
                  synchronized {
                      if(foo==null)    foo=new Singleton();
                  }
              }
           return foo;
        }

Rating: 2.9/5 (14 votes cast)

推荐购买的书籍--都是牛书
  1. 1 Trackback(s)

  2. Aug 25, 2008: 再考虑singleton在Java中的实现的一些问题 | Semantic Web Notes

我来说下

关于

我叫陈炬,正在天津大学计算机学院->知识工程与科学研究所攻读硕士研究生。今年应届。您可以在我的自我介绍获得更多关于我的信息

订阅我的Blog


本站RSS地址| [这是什么?]
订阅到Google Reader | 订阅到 抓虾 阅读器 | 订阅到 鲜果 阅读器

其他blog

我还有一个英文blog,非常的无聊,琐碎,许多的语法错误。请谨慎访问。
Find entries :