zoukankan      html  css  js  c++  java
  • 单例模式实现 (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 

  • 相关阅读:
    Apache Tomcat 6.0 Tomcat6 服务因 1 (0x1) 服务特定错误而停止
    PaodingAnalysis 提示 "dic home should not be a file, but a directory"
    mappingDirectoryLocations
    多级反向代理下,Java获取请求客户端的真实IP地址多中方法整合
    java.util.ResourceBundle
    JSP验证码
    Error: [ng:areq] Argument 'LoginCtrl' is not a function, got undefined
    《横向领导力》笔记
    Java执行定时任务
    2017第43周三
  • 原文地址:https://www.cnblogs.com/liaotongquan/p/3001738.html
Copyright © 2011-2022 走看看