您的位置:首页 > 其它

设计模式之Singleton - 单态模式

2008-06-25 22:11 169 查看

Singleton模式也叫单态模式,是由GoF提出的23种设计模式中的一种。Singleton模式是一种对象创建型模式,它为一个类生成唯一的实例对象,并提供一个对该实例的全局访问方法。

本文介绍设计模式中的单态(Singleton)模式的概念,用法,以及实际应用中怎么样使用Singleton模式进行开发。

Singleton的概念
Singleton模式是一种对象创建型模式,使用Singleton模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。

其实,GoF对Singleton模式的定义是:保证一个类只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。

为什么要使用Singleton模式呢?
在应用系统开发中,我们常常有以下需求:

- 在多个线程之间,比如servlet环境,共享同一个资源或者操作同一个对象

- 在整个程序空间使用全局变量,共享资源

- 大规模系统中,为了性能的考虑,需要节省对象的创建时间

等等

因为Singleton模式可以保证为一个类只生成唯一的实例对象,所以这些情况,Singleton模式就派上用场了。

Singleton模式的实现
Singleton模式是设计模式中相对比较简单的模式之一。理解以及使用方法都比较简单。

Singleton模式有多个实现方法。但目前,每一种都存在或多或少的问题。

下面我们将给出几种实现方法,同时对它们加以比较。

第一种方法:

这是一种最简单的实现方法。但是一种相对有效的实现方法。现在,一般推荐这一种方法作为Singleton模式的实现方法。

//1)使用final关键字修改class,防止子类继承

public final class Singleton {

//2)Singleton自身唯一实例instance

private static final Singleton instance = new Singleton();

//3)private构造方法。防止外部调用者使用new创建新的实例

private Singleton(){};

//4)提供唯一实例的全局访问点

public static Singleton getInstance(){

return Singleton.instance;

}

...

}

注意上述1),2),3),4)部分,这是Singleton模式实现的几个关键。

我们注意到,这种方法没有对instance = new Singleton()部分作同期化操作,但考虑到Singleton实例的生成只是在最初被调用时才执行一次,如果我们在调用时适当处理一下,比如在程序的统一初期化时(SERVLET环境的情况下可以在容器被初始化时如SevletListener里)调用一下Singleton,就不会存在线程安全问题。

第二种方法:

public final class Singleton {

private static Singleton instance;

private Singleton(){};

public static synchronized Singleton getInstance(){

if(instance == null){

instance = new Singleton();

}

return instance;

}

}

该方法把Singleton实例生成放到了getInstance方法里,同时使用synchronized解决了线程安全问题。

但如果在高并发的应用系统中,大量的线程在调用getInstance时会受到阻塞,系统的性能将受到严重影响。

第三种方法:

public final class Singleton {

private static Singleton instance;

private Singleton(){};

public static Singleton getInstance(){

if(instance == null){

synchronized (this) {

//double-check

if(instance == null){

instance = new Singleton();

}

}

}

return instance;

}

}

该方法也叫double-check(双重检查)方法,把线程同步synchronized放到只会被执行一次的同步块里。该方法虽然解消了性能瓶颈问题,但该方法被指出并不是线程安全的(不同步的情况下引用类型不是线程安全的)。

第四种方法:

public final class Singleton {

private volatile static Singleton instance;

private Singleton(){};

public static Singleton getInstance(){

if(instance == null){

synchronized (this) {

//double-check

if(instance == null){

instance = new Singleton();

}

}

}

return instance;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: