首页 > 学院 > 开发设计 > 正文

C#设计模式-单实例

2019-11-17 02:44:09
字体:
来源:转载
供稿:网友

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
可以看到这两个实例都来自一个实例。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表