zoukankan      html  css  js  c++  java
  • 设计模式之-单例模式

    前言

    通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。

    Singleton类,定义一个GetInstance操作,允许客户访问它的唯一实例。GetInstance是一个静态方法,主要负责创建自己的唯一实例。

     class Singleton
        {
            private static Singleton instance;
    
            //构造方法让其private,这就堵死了外界利用new创建此类实例的可能
            private Singleton()
            {
            }
    
            //此方法是获得本类实例的唯一全局访问点
            public static Singleton GetInstance()
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }

    客户端代码

     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();
            //构造方法让其private,这就堵死了外界利用new创建此类实例的可能
            private Singleton()
            {
            }
    
            //此方法是获得本类实例的唯一全局访问点
            public static Singleton GetInstance()
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
                return instance;
            }
        }

    lock是锁的意思,再同一时刻加了锁的那一部分,只有一个线程可以进入。

    但是这样做并不是最好的,程序每次进来都会lock,会比较影响性能,所以我们可以使用双重锁定。

     class Singleton
        {
            private static Singleton instance;
            //程序运行时创建一个只读的进程辅助对象
            private static readonly object syncRoot = new object();
            //构造方法让其private,这就堵死了外界利用new创建此类实例的可能
            private Singleton()
            {
            }
    
            //此方法是获得本类实例的唯一全局访问点
            public static Singleton GetInstance()
            {
                //先判断实例是否存在,存在直接返回,不存在再进入锁
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }
        }

    再lock外层增加了一个实例是否存在的判断,看起来程序多用了一个无用判断,其实不然,最外层判断是判断实例是否存在,如果不存在,就加锁创建,如果没有里面一层判断,那当多线程使用时,可能同时两个线程越过第一重判断,进而多次实例化,这并不是我们想要的结果。所以,解决多线程单例的推荐方式是双重锁

  • 相关阅读:
    数制转换
    禁止用户复制网页的内容
    TdxDBTreeView的节点移动排序
    cxgrid根据字段设置颜色
    获取用户IP
    在sql server中用存储过程发送邮件
    Delphi的DTS编程
    使年份适用于做有浏览器(IE和FireFox)
    用Delphi写扬声器音乐
    过滤字符串中的HTML代码(VBScript)
  • 原文地址:https://www.cnblogs.com/zhangxiaoyong/p/7218088.html
Copyright © 2011-2022 走看看