我们在键盘上跳舞,演绎最美的人生

单例模式实现 (Singleton)

第一个版本:

 1 // Bad code! Do not use!
 2 public sealed class Singleton
 3 {
 4     private static Singleton instance=null;
 5 
 6     private Singleton()
 7     {
 8     }
 9 
10     public static Singleton Instance
11     {
12         get
13         {
14             if (instance==null)
15             {
16                 instance = new Singleton();
17             }
18             return instance;
19         }
20     }
21 }

这个用例是线程不安全的,两个不同线程完全可能同时进入if (instance==null)并进行判断得出结果都为True,此时两个线程都将会去创建各自的实例对象,这就跟单例模式违反了。 

第二个版本:

 1 public sealed class Singleton
 2 {
 3     private static Singleton instance = null;
 4     private static readonly object padlock = new object();
 5 
 6     Singleton()
 7     {
 8     }
 9 
10     public static Singleton Instance
11     {
12         get
13         {
14             lock (padlock)
15             {
16                 if (instance == null)
17                 {
18                     instance = new Singleton();
19                 }
20                 return instance;
21             }
22         }
23     }
24 }

第二个版本成功解决了第一个版本中存在的线程不安全的问题---加入了锁机制。但问题也随之而来,加入锁机制后,每次要获取instance都会先判断是否被锁,在这里,都讲成为单管道,效率明显减低。

 

第三个版本:

 1 // Bad code! Do not use!
 2 public sealed class Singleton
 3 {
 4     private static Singleton instance = null;
 5     private static readonly object padlock = new object();
 6 
 7     Singleton()
 8     {
 9     }
10 
11     public static Singleton Instance
12     {
13         get
14         {
15             if (instance == null)
16             {
17                 lock (padlock)
18                 {
19                     if (instance == null)
20                     {
21                         instance = new Singleton();
22                     }
23                 }
24             }
25             return instance;
26         }
27     }
28 }

为了解决第二个版本中的效率问题,在第三个版本中修改了锁机制,但这样真的就解决问题了吗?还真没有。具体见http://csharpindepth.com/Articles/General/Singleton.aspx#dcl

第四个版本:

 1 public sealed class Singleton
 2 {
 3     private static readonly Singleton instance = new Singleton();
 4 
 5     // Explicit static constructor to tell C# compiler
 6     // not to mark type as beforefieldinit
 7     static Singleton()
 8     {
 9     }
10 
11     private Singleton()
12     {
13     }
14 
15     public static Singleton Instance
16     {
17         get
18         {
19             return instance;
20         }
21     }
22 }

第四版本很好的取消掉了锁机制带来的问题,但还是没有解决懒惰加载的问题。

 

第五个版本:

public sealed class Singleton
{
    private Singleton()
    {
    }

    public static Singleton Instance { get { return Nested.instance; } }
        
    private class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}

更好的第六个版本:(使用4.0+)

 1 public sealed class Singleton
 2 {
 3     private static readonly Lazy<Singleton> lazy =
 4         new Lazy<Singleton>(() => new Singleton());
 5     
 6     public static Singleton Instance { get { return lazy.Value; } }
 7 
 8     private Singleton()
 9     {
10     }
11 }

扩展的第七个版本:

 1 /// <summary>
 2 /// A base class for the singleton design pattern.
 3 /// </summary>
 4 /// <typeparam name="T">Class type of the singleton</typeparam>
 5 public abstract class SingletonBase<T> where T : class
 6 {
 7   #region Members
 8 
 9   /// <summary>
10   /// Static instance. Needs to use lambda expression to construct an instance (since constructor is private).
11   /// </summary>
12   private static readonly Lazy<T> sInstance = new Lazy<T>(() => CreateInstanceOfT());
13 
14   #endregion
15 
16   #region Properties
17 
18   /// <summary>
19   /// Gets the instance of this singleton.
20   /// </summary>
21   public static T Instance { get { return sInstance.Value; } }
22 
23   #endregion
24 
25   #region Methods
26 
27   /// <summary>
28   /// Creates an instance of T via reflection since T's constructor is expected to be private.
29   /// </summary>
30   /// <returns></returns>
31   private static T CreateInstanceOfT()
32   {
33     try
34     {
35       return Activator.CreateInstance(typeof(T), true) as T;
36     }
37     catch (MissingMethodException ex)
38     {
39       throw new TypeLoadException(
40         string.Format(
41           System.Globalization.CultureInfo.CurrentCulture,
42           "The type '{0}' must have a private constructor to be used in the Singleton pattern.",
43           typeof(T).FullName),
44           ex);
45     }//end try/catch
46   }
47 
48   #endregion
49 } 

参考:

http://csharpindepth.com/Articles/General/Singleton.aspx

http://www.codeproject.com/Articles/572263/A-Reusable-Base-Class-for-the-Singleton-Pattern-in 

 

 

posted @ 2013-04-05 23:05  嘉应子  阅读(229)  评论(0编辑  收藏  举报