単例模式

本文详细介绍了单例模式的概念、作用,以及如何通过双重锁定(Double-Check Locking)实现线程安全的单例。讨论了饿汉式和懒汉式的区别,探讨了单例模式的优缺点,并提到了与实用类的区别,指出单例类具有状态且可继承,而实用类提供静态方法和属性,不保存状态。
摘要由CSDN通过智能技术生成

単例模式:

    这是一个很好理解的模式;该模式保证一个类仅有一个实例,并提供一个访问他的全局访问点。可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

结构图:


代码实例:

 class Program
    {
        static void Main(string[] args)
        {
            Singleton s1 = Singleton.GetInstance();//调用方法
            Singleton s2 = Singleton.GetInstance();
            if (s1==s2 )//判断
            {
                Console.WriteLine("两个对象时相同的实例");
            }
            Console.Read();
        }
    }
    class Singleton
    {
        private static Singleton instance;//类变量声明                                
        //运行时创建 的 静态只读  的  进程辅助对象
        private static readonly object syncRoot = new object();

        //私有化,堵死了外界利用new创建此类实例的可能
        private Singleton()//控制客户怎么访问,何时访问(受控访问)
        { }
        public static Singleton GetInstance()//唯一的全局访问点
        {
            if (instance == null)//如果没有实例则加锁创建实例
            {
                lock (syncRoot)//加锁,同一时刻只有一个线程可以进入
                {
                    if (instance == null)//实例不存在,new
                    {
                        instance = new Singleton();//此时实例化:懒汉式単例
                    }
                }
            }
            return instance;//有实例直接返回
        }
    }

加锁(lock syncRoot)

    是为了解决多个线程同时访问Singleton类,调用GetInstance()方法,创建多个实例的情况。更进一步为了不尽可能少的影响性能,保证多线程的安全,这里加了两次锁——双重锁定(Double-Check Locking), 对于双重锁定的解析,结合上面的代码更好理解:两次判断对象是否为空,这两个判断分别在临街区外和临界区内,前者是为了不至于每次调用getInstance方法都要加锁,减小了系统开销;另外当有一个线程进入临界区时,其它线程也通过了对象为空的条件判断,导致最后创建了多个对象情况的发生,后者则是为了防止这种情况的发生,即所谓“双重锁定”。

饿汉与懒汉:

    上面注释也说到了这是一个懒汉式的単例模式;主要是说在第一次被引用的时类,变量才将自己实例化;与之对应的是饿汉式単例:即在自己被加载时就将自己实例化,代码如下:

  public sealed class Singleton//sealed阻止发生派生(可能增加实例)
    {
        //第一次引用时创建实例,公共语言运行库负责处理变量初始化(饿汉式単例类)
        //readonly只能在静态初始化期间或类构造函数中分配变量
        private static readonly Singleton instance = new Singleton();
        private Singleton() 
        { }
        public static Singleton GetInstance()
        {
            return instance;
        }
    }

派生: 

   从已有的类(父类)产生一个新的子类,称为类的派生。派生类是基类的具体化,而基类则是派生类的抽象。

公共语言库

   看不太懂,或者大家看懂了帮忙解释一下:链接http://baike.so.com/doc/5947088-6160025.html

优缺点:

1、因为类控制了实例化过程,所以类可以灵活更改实例化过程。

2、单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。

1.开发人员必须记住自己不能使用new关键字实例化对象。

2.如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。

3.不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。

与实用类:

实用类网络上相关的解释也是模棱两可的,百科中概述为:在编程的过程当中实际的使用率很高,操作性比较简单的类(Date类等);实用类和単例有很多相似的地方,比如:实用类通常也采用私有化的构造方法避免其有实例,但是两者还是有很多不同的地方。

1、实用类不保存状态,仅提供一些静态方法或属性;単例类有状态

2、实用类不能用于继承多态,単例虽然实例唯一,可以有子类来继承

3、实用类不过是方法属性的集合,単例有着唯一的对象实例。

thanks for your time,欢迎交流


评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值