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

  • 相关阅读:
    2015第18周四
    2015第18周三程序员能力
    2015第18周二
    2015第18周一
    2015第17周日活在当下
    2015第17周六去除表中某字段重复记录
    2015第17周五
    2015第17周四
    Mac OS X Yosemite安装Hadoop 2.6记录
    GLEW_ERROR_NO_GL_VERSION的解决方法
  • 原文地址:https://www.cnblogs.com/zhangxiaoyong/p/7218088.html
Copyright © 2011-2022 走看看