簡體   English   中英

這兩個Singleton實現之間的區別

[英]Difference between these two Singleton implementations

我正在學習如何實現一些基本的設計模式。 在學習Singleton模式的同時,我注意到Web上有兩種常見的實現:

// Possibly from: http://www.yoda.arachsys.com/csharp/singleton.html
// I cannot remember exact source, sorry :(

public sealed class Singleton
{
    // Static members are 'eagerly initialized', that is,
    // immediately when class is loaded for the first time.
    // .NET guarantees thread safety for static initialization
    private static readonly Singleton instance = new Singleton();

    // Private constructor prevents instantiation from other classes
    private Singleton() { }

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    public static Singleton() { }

    // Get the instance of the singleton
    public static Singleton getInstance()
    {
            return instance;
    }

}

和:

public class Singleton
{
  // Static, VOLATILE variable to store single instance
  private static volatile Singleton m_instance;

  // Static synchronization root object, for locking
  private static object m_syncRoot = new object();

  // Property to retrieve the only instance of the Singleton
  public static Singleton Instance
   {
      get
      {
          // Check that the instance is null
          if (m_instance == null)
          {
              // Lock the object
              lock (m_syncRoot)
              {
                  // Check to make sure its null
                  if (m_instance == null)
                  {
                      m_instance = new Singleton();
                  }
              }
          }

          // Return the non-null instance of Singleton
          return m_instance;
      }
  }
} 
  1. 在什么情況下你會選擇急切地初始化vs lazy初始化?
  2. 第一個例子中的注釋是否正確,說初始化是線程安全的? (我知道它說的是,但它是互聯網...)

我絕對會選擇你的第一個......

第二個對我來說似乎有問題...如果你需要/想要一個懶惰的實現,你可以使用Lazy<T> - 因為它是框架的一部分,感覺更舒服..

順便說一下:有更多的方法來實現Singleton模式...... 這是一篇很棒的文章

我不確定,但看起來你從這里得到了這些例子: http//www.yoda.arachsys.com/csharp/singleton.html

如果沒有,請仔細閱讀。 關於這兩個版本有幾點想法。 如果你個人問我:如果我需要知道單身是否已經初始化,我會選擇第二個解決方案。

如果您不必處理多線程,我會使用更簡單的方法(請參閱參考鏈接中的“錯誤代碼”示例)。

第一個是安全和懶惰的。

保證static constructor只執行一次,並且在第一次訪問Instrance之前立即執行。 如果存在靜態構造函數(即使為空),則保證靜態字段初始化直接在靜態構造函數之前執行。 如果沒有靜態構造函數,則字段初始化可能更早發生。


第二個是懶惰的,但我不確定雙鎖模式是否有效。 我懷疑它已經壞了,至少在ECMA內存模型中是這樣。


就個人而言,在大多數情況下,我會避免使用任何Class.Instance單例模式來支持IoC單例。

1)這完全是一種設計選擇。 在需要時預先啟動或初始化。

2)是的,它是線程安全的,因為CLR保證單線程對象初始化。 (靜態和實例)

編輯

就個人而言,在第一個例子中,我將Instance字段公之於眾,並免除了getter。 有興趣知道這是不是一個壞主意?

這是一個單身人士所以我會選擇第一選項,除非它是一個並不總是需要的大型物體。 但我可能不會為那些通常根本沒用過的東西做單身。

兩種實現都很好,所以它取決於你需要什么。

如果性能不是問題,請使用第一個的熱切創建的實例。 否則,使用第二個,其中僅同步第一個訪問。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM