单件模式
2011-09-20 17:34 xiashengwang 阅读(254) 评论(0) 编辑 收藏 举报主要是从网上找一些资料学习,练习,所以例子主要来自于网上,特别感谢牛人Terrylee,他的博客里有很多设计模式的文章,主要就是从他那里学习,讲得非常好,大家可以到哪里去看看。博客地址:http://terrylee.cnblogs.com/ 。本博客只是照着练习的例子,供个人查阅,批注。
一,概念
1) 意图
保证一个类只有一个实例,并提供一个访问它的全局访问点。
二,练习代码
using System; using System.Collections.Generic; using System.Text; namespace CsharpBase.DesignPattern.Singleton { /// <summary> /// 名称:单件模式 /// 保证一个类只有一个实例,并提供一个对他的全局访问点 /// </summary> /// <remarks> /// 注意: /// 1,单列模式的类应该只允许一个static的全局访问点,这里的允许是设计者应该 /// 考虑的问题,是设计者的责任。而不是类成为Singleton后,只会提供一个static的静态方法 /// 他同样可以有很多个静态的Public方法或成员。 /// </remarks> class SingletonDemo { public static void Run() { CountMultiThread.MultiMain(); } } /// <summary> /// 简单实现 /// </summary> sealed class Singleton { private static Singleton instance; /// <summary> /// private constructor /// </summary> Singleton() { } public static Singleton Instance() { if (instance == null) { instance = new Singleton(); } return instance; } } /// <summary> /// 线程安全 /// </summary> class Singleton2 { /// <summary> /// private static instance /// </summary> private static Singleton2 instance; private static object syncLock = new object(); /// <summary> /// private constructor /// </summary> Singleton2() { } public static Singleton2 Instance() { lock (syncLock) { if (instance == null) { instance = new Singleton2(); } } return instance; } } /// <summary> /// 双重锁定 /// </summary> class Singleton3 { private static Singleton3 instance; private static object syncLock = new object(); Singleton3() { } public static Singleton3 Instance() { if (instance == null) { lock (syncLock) { if (instance == null) { instance = new Singleton3(); } } } return instance; } } /// <summary> /// 静态初始化(继承) /// </summary> class Singleton4 { private static readonly Singleton4 instance = new Singleton4(); static Singleton4() { instance = new Singleton4(); } protected Singleton4() { } public static Singleton4 Instance() { return instance; } public void WriteType() { Console.WriteLine("Object Type=" + this.GetType().Name); } } class SingleChild : Singleton4 { private static readonly SingleChild instance = new SingleChild(); SingleChild() { } public static new SingleChild Instance() { return instance; } public void WriteMe() { Console.WriteLine("chile invoded"); } } /// <summary> /// 静态初始化 /// </summary> sealed class Singleton5 { private static readonly Singleton5 instance = new Singleton5(); static Singleton5() { } Singleton5() { } public static Singleton5 Instance { get { return instance; } } } /// <summary> /// 静态初始化(延迟初始化) /// </summary> /// <remarks> /// 此例将静态私有变量放到Nested中返回,这样可以延迟初始化。 /// 原因:当对类的任何成员的第一次引用是,会初始化静态成员变量。 /// </remarks> sealed class Singleton6 { Singleton6() { } public static Singleton6 Instance() { return Nested.instance; } public static string ToStr() { return "abc"; } internal class Nested { Nested() { } public static Singleton6 instance = new Singleton6(); } } #region sample sealed class CountSingleton { private static readonly CountSingleton instance = new CountSingleton(); private static int num =0; static CountSingleton() { } CountSingleton() { } public static CountSingleton Instance() { return instance; } public void Add() { num++; } public int GetCounter() { return num; } } public class CountMultiThread { private static object objLock = new object(); private static void DoSomeWork() { CountSingleton myCounter = CountSingleton.Instance(); //lock (objLock) //{ for (int i = 0; i < 5; i++) { //这里要用lock,不然add和getcounter可能不同步。中间可能会进入其他的线程, //如果要保证每个线程执行五次的话lock的位置要处于for外面。 lock (objLock) { myCounter.Add(); string strResult = "theadName:" + System.Threading.Thread.CurrentThread.Name; strResult += ",Counter:" + myCounter.GetCounter(); Console.WriteLine(strResult); } } Console.WriteLine("------------------------"); //} } public static void MultiMain() { System.Threading.Thread t0 = System.Threading.Thread.CurrentThread; t0.Name = "thread0"; System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ThreadStart(DoSomeWork)); t1.Name = "thread1"; System.Threading.Thread t2 = new System.Threading.Thread(new System.Threading.ThreadStart(DoSomeWork)); t2.Name = "thread2"; System.Threading.Thread t3 = new System.Threading.Thread(new System.Threading.ThreadStart(DoSomeWork)); t3.Name = "thread3"; System.Threading.Thread t4 = new System.Threading.Thread(new System.Threading.ThreadStart(DoSomeWork)); t4.Name = "thread4"; t1.Start(); t2.Start(); t3.Start(); t4.Start(); DoSomeWork(); } } #endregion }