温故而知新:设计模式之单件模式(Singleton)

 1 using System;
 2 
 3 namespace Singleton
 4 {
 5     class Program
 6     {
 7         static void Main(string[] args)
 8         {
 9             Singleton s1 = Singleton.Instance;
10             Singleton s2 = Singleton.Instance;
11 
12             Console.WriteLine(object.ReferenceEquals(s1, s2));
13 
14             Console.Read();
15         }
16     }
17 
18 
19 
20     //线程安全的单件写法
21     sealed class Singleton //sealed并非必要,看需求而定
22     {
23         private Singleton() { }//私有构架器的目的是为了防止编译器自动创建默认的公用构架器(从而阻止了用户new类的实例)
24 
25         private static volatile Singleton _instance;//valatile关键字用于声明该代码不会被编译器自动优化,从而更严格的保证了单件的实现
26 
27         private static object _lockHelper = new object();//同步锁辅助对象
28 
29         //定义一个只读实例属性
30         public static Singleton Instance
31         {
32             get
33             {
34                 if (_instance == null//初次检测,以防止多次创建实例
35                 {
36                     //#1
37                     lock (_lockHelper) //多线程环境下,极有可能多个线程“同时”运行到这里,所以如果不用同步锁,有可能会出现多个线程“同时”创建多个实例
38                     {
39                         if (_instance == null//二次检查以防止创建多个实例(解释:如果不加此句,假设有二个线程同时进入#1处,第一个线程锁定-->创建实例-->解锁 到达#2处,第二个线程还留在#1处,同样还是会创建第二个实例,换言之:加锁的目的是为了防止多个线程同时创建,让线程强制有先后顺序,然后用二次检查来防止重复创建
40                         {
41                             _instance = new Singleton();
42                         }
43                     }
44                     //#2
45                 }
46                 return _instance;
47             }
48         }
49     }
50 
51 
52     #region  //这是c#语言中特有的优雅实现方式
53     //sealed class Singleton //sealed并非必要,看需求而定
54     //{
55     //    public static readonly Singleton Instance = new Singleton();
56 
57     //    private Singleton() { }
58     //}
59 
60     //上面的代码等同于
61 
62     //sealed class Singleton 
63     //{
64     //    public static readonly Singleton Instance; //因为静态属性初始化后,仍然有可能被赋值修改,所以必须加上readonly以保证单件实例不再被修改的初衷
65 
66     //    static Singleton() //静态构造器,会在静态成员初次访问前被调用,同时编译器会自动给静态构造器加锁/解锁,所以该方法同样适合于多线程(线程安全)
67     //    {
68     //        Instance = new Singleton();
69     //    }
70 
71     //    private Singleton() { }
72     //}
73     #endregion
74 }
75 

 Singleton的精髓在于:对于类的实例个数做了限制,只要领会了这一点,可以应用到很多场景,比如聊天室最多只能让100个人进来,数据库连接实例只能有200个...

posted @ 2010-01-18 17:09  菩提树下的杨过  阅读(562)  评论(0编辑  收藏  举报