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(); } } }
可以看到这两个实例都来自一个实例。
作者:KeithMorning
出处:http://www.cnblogs.com/keithmoring/
关于作者:欢迎转载,且在文章页面明显位置给出原文链接
如有问题,可以通过keith@keithmorning.com 联系我,非常感谢。