设计模式之Singleton - 单态模式

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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值