• C#设计模式-单实例


    单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点。

    1.经典的模式

    namespace singleClass
    {
        class OnlyOneClass
        {
            private OnlyOneClass() { }
            private static OnlyOneClass instance;
            public static OnlyOneClass getInstance() {
                if (instance == null) {
                        instance = new OnlyOneClass();
                        return instance;
                }
                return instance;
            }
        }
    }

    分析一下:

    1)通过私有化构造函数,使该类被调用的时候不能通过new来实现

    2)定义一个静态变量类,它的生命周期和程序的生命周期是一样的,通过该静态变量来保存该类的实例

    2)通过一个静态方法来实例化自己,并返还实例化后的结果,因为该方法先检查全局的实例,再判断是否再创建,保证只有一个实例

    但是,这种方式如果碰到了多线程并发,问题就来了,如A,B两个线程同时访问了这个类,第一次检查时候都是null,会出现两个同时建立自己实例情况,这样就违背单实例模式的原则

    改进一下后:

    2.俗称懒汉模式

    namespace singleClass
    {
        class OnlyOneClass
        {
            private OnlyOneClass() { }
            public string thisname;
            private static OnlyOneClass instance;
            private static object _lock = new object();
            public static OnlyOneClass getInstance() {
                if (instance == null) {
                    lock (_lock)
                    {
                        if (instance == null)
                        {
                            instance = new OnlyOneClass();
                            return instance;
                        }
                    }
                }
                return instance;
            }
        }
    }

    解析:

    1)声明一个object 变量,作为lock对象

    2)先判断instance的变量是否为null,如果不为null也就不用lock了,直接返回实例

    3) 如果是null,锁定对象,继续判断是否为null,以防有其他线程在lock前已经新建了实例,lock后可以保证在一个线程内操作

    3.饿汉模式

    class HungerClass{
            private HungerClass() { }
            private readonly static HungerClass instance=new HungerClass ();
            public static HungerClass getInstance(){
                return instance;
            }
        }
    可以看出这种模式是在类初始化后就已经实例化了instance,不同于上面的懒汉模式时在调用getInstance()方法后实例化。
    这种方式下,线程安全的问题将交给CLR。
     
    
    

    4.测试

    演示一下,通过声明两个OneClass类,只一个对其的thisname赋值,然后输出这两个类的thisname,看看另一个会怎样
    class Program
        {
            
            static void Main(string[] args)
            {
                Console.WriteLine("Get a instanc from OnlyOneClass!");
                try {
                    OnlyOneClass one = OnlyOneClass.getInstance();//one 第一个类的变量
            
                    Console.WriteLine(one.ToString());
                    
                      while(true){
                          string ins = Console.ReadLine();
                          if (ins != "") { one.thisname = ins; }//只对one实例的thisname赋值
                          OnlyOneClass two = OnlyOneClass.getInstance();//two 第二个类的变量
                          Console.WriteLine(one.thisname +" one");//输出 one实例的thisname
                          Console.WriteLine(two.thisname +" two"); //输出 two实例的thisname
                          Thread.Sleep(1000);
                      }
                }
                catch (Exception e) {
                    Console.WriteLine(e.Message);
                }
               
                Console.ReadKey();
            }
        }
    }
    image
    可以看到这两个实例都来自一个实例。
     
     
  • 相关阅读:
    Swift中枚举的总结以及使用
    CapsLock Enhancement via AutoHotKey
    计算思维
    计算几何-凸包算法 Python实现与Matlab动画演示
    CapsLock魔改大法——变废为宝实现高效编辑
    Python调用Matlab2014b引擎
    VC++如何利用Matlab2014b的图形引擎进行绘图
    Window中C++进行精确计时的方法
    十四。算法小知识点
    十三。宫水三叶公众号总结
  • 原文地址:https://www.cnblogs.com/keithmoring/p/4122499.html
Copyright © 2020-2023  润新知