设计模式之Singleton

现实生活中有很多唯一的概念,如: 一个联合国秘书长,一个中国,一夫一妻制等等,多了怕要出问题.

我们知道对象都是New出来的,要保证对象的唯一关键在于控制对象的创建权.所谓只允许官家放火,不许百姓点灯.官家只有一个,可以负责创建,要是随随便便让百姓点把火,怕是到处要遭火灾了.

public class Singleton
{
    private Singleton() {}
}

保证了类不能被client创建.那问题来了,client怎么访问呢,官方负责创建,并提供访问的入口.

private static Singleton m_instance = new Singleton();
public static Singleton Instance
{
    get { return m_instance; }
}

此为"饿汉式单例类",因为此类一般加载就会调用类的静态构造函数,创建了类的实例.

相比有"懒汉式单例类",

public class Singleton
{
    private static Singleton m_instance = null;
    private Singleton() { }
    public static Singleton Instance
    {
        get
        {
            if (m_instance == null)
                m_instance = new Singleton();
            return m_instance;
        }
    }
}

改进的地方在于延迟了类的创建,但相比"饿汉式单例类"确有致命弱点,存在线程安全问题.编译器能够保证静态构造函数只被调用一次,所以"饿汉式单例类"是没有这个问题的.

改进方法很简单,加个锁.

private static object m_locker = new object();

get
{
    lock (m_locker)
    {
    if (m_instance == null)
        m_instance = new Singleton();
    return m_instance;
}

注意此锁对象必须为static,因为要保证在调用Instance方法前,此对象就被创建完毕.

有人说,这样不是类在加载的时候也需要创建了一个静态变量实例吗.对,你观察的很仔细,但是你要知道一个object实例对象的创建一般要比Singleton实例的创建开销小的多.

此加锁方法仍然存在严重的性能问题,要知道Singleton创建只有一次,但却可能被多线程频繁访问,访问一下加一下锁,怎么能保证并发访问的效率呢?

这时候双重锁,派上了用场了.

if (m_instance == null)
{
    lock (m_locker)
    {
        if (m_instance == null)
            m_instance = new Singleton();
    }
}
return m_instance;

这样就是一个比较完美的解决方案了,既做到了延迟创建,又保证了多线程安全,同时也保证了效率.只有第一次对象为null时,要加次锁,开销不大.

最后要注意的地方就是在lock段里面还是要判断m_instance是否为null,要不然在并发的时候还是能创建多个对象的哦.

 

实际应用:

经常应用于读取配置文件啥的,一些Manager类啥的

和工厂模式一起使用,class loader等

Remoting Server激活方式有种就是Singleton

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值