Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4206973
  • 博文数量: 176
  • 博客积分: 10059
  • 博客等级: 上将
  • 技术积分: 4681
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-24 12:27
文章分类

全部博文(176)

文章存档

2012年(1)

2011年(4)

2010年(14)

2009年(71)

2008年(103)

分类: 项目管理

2008-06-16 23:22:56

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;
    }
}
该方法在第三种方法的基础上,为Singleton instance的定义加上volatile关键字修饰,该方法也被称为double-check volatile方法。但该方法却依奈不同的编译器。也就是说,在某些编译环境中,第四种方法也是非线程安全的。
阅读(1664) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~