在程序开发中,经常遇到一类问题:在不同的场合(类,对象)中需要调用一个对象。在某型场合可以使用全局对象来实现,比如在web中可以使用Application来解决这个问题。
很多场合给出的非多线程的情况下单件模式的实现代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SingleTon { class Program { static void Main(string[] args) { SingelClass s1 = SingelClass.Instance(); SingelClass s2 = SingelClass.Instance(); if (s1.Equals(s2)) { Console.Write("是一个"); }else{ Console.Write("不是一个"); } Console.Read(); } } class SingelClass{ private static SingelClass mySingelClass = null; private SingelClass(){ } public static SingelClass Instance(){ if (mySingelClass==null) { mySingelClass = new SingelClass(); } return mySingelClass; } } }
多线程的单件模式的实现如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SingleTon { class Program { static void Main(string[] args) { SingelClass s1 = SingelClass.Instance(); SingelClass s2 = SingelClass.Instance(); if (s1.Equals(s2)) { Console.Write("是一个"); }else{ Console.Write("不是一个"); } Console.Read(); } } class SingelClass { public static SingelClass Instance() { if (_instance == null) { lock (typeof(SingelClass)) { if (_instance == null) { _instance = new SingelClass(); } } } return _instance; } protected SingelClass() { } private static volatile SingelClass _instance = null; } }
简单一些的singleton模式可以设计如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SingleTon { class Program { static void Main(string[] args) { SingelClass s1 = SingelClass.Instance(); SingelClass s2 = SingelClass.Instance(); if (s1.Equals(s2)) { Console.Write("是一个"); }else{ Console.Write("不是一个"); } Console.Read(); } } class SingelClass { public static readonly SingelClass _instance = new SingelClass(); private SingelClass() { } } }
当然,根据上述几个,可以经过演绎出来更多的代码,不过目前来看,第三个代码是最简单的实现代码。
说到单件模式。很容易遇到的一个情况是这样的。多线程的互斥情况的一些情况(asp.net中要对一个数据进行操作时候的锁定):如我们要对某个资源进行处理,在处理完成前不允许其他方法和对象对该资源进行处理。 singleton模式通常指的是要求一个对象,实例化一个对象;而是多线程的互斥通常指的是多个线程同时访问一个资源的时候进行列队进行,同一时间只允许某一种;或者某一类的操作。
在对同一个对象的不同的线程操作中:可以使用下面的lock代码。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace SingleTon { class Program { static void Main(string[] args) { SingelClass mySg = new SingelClass(); Thread t1 = new Thread(new ThreadStart(mySg.Test1)); Thread t2 = new Thread(new ThreadStart(mySg.Test2)); t1.Start(); t2.Start(); Console.Read(); } } class SingelClass { private object myObj = new object(); public void Test1() { lock(myObj){ Thread.Sleep(1000); Console.Write("Test1/r/n"); } } public void Test2(){ lock(myObj){ Console.Write("Test2/r/n"); } } } }
要在全局对某个资源进行互斥的话:
可以使用SingleTon模式结合上述的代码进行。或者把 lock 的对象设置为static
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace SingleTon { class Program { static void Main(string[] args) { SingelClass mySg = new SingelClass(); SingelClass mySg2 = new SingelClass(); Thread t1 = new Thread(new ThreadStart(mySg.Test1)); Thread t2 = new Thread(new ThreadStart(mySg2.Test2)); t1.Start(); Thread.Sleep(100); t2.Start(); Console.Read(); } } class SingelClass { private static object myObj = new object(); public void Test1() { lock (myObj) { Thread.Sleep(1000); Console.Write("Test1/r/n"); } } public void Test2(){ lock(myObj){ Console.Write("Test2/r/n"); } } } }
关于Mutex对象的详细用见:
详细的见:http://msdn.microsoft.com/zh-cn/library/ms173179(v=VS.80).aspx