2017-05-28 90 views
2

我是新來設計C#模式。任何人都可以給我一些關於Singleton類的實現的說明。我剛剛實現了一個教程,但我無法理解單例類的使用,這個「單例表示我們只能創建一個類的一個實例」。那麼爲什麼我們不使用兩個不同類的實例訪問單例類中寫入的屬性。單個類的兩個實例是否具有相同的屬性值?

請看我的代碼,並給我說明我犯的錯誤。

static void Main(string[] args) 
{ 

    Singleton instance = Singleton.getInstance(); 
    instance.Message = "Text Message"; 

    Singleton instance1 = Singleton.getInstance(); 
    Console.WriteLine(instance.Message); 
    Console.WriteLine(instance1.Message); 
    Console.ReadKey(); 
} 

class Singleton 
{ 
    private static Singleton singleton=null; 
    private Singleton(){} 
    public static Singleton getInstance() 
    { 
     if (singleton!=null) 
     { 
      return singleton; 
     } 
     return new Singleton(); 
    } 
    public string Message{get; set;} 
} 
+5

如果有兩個實例,它不是一個單例。 –

+2

,因爲這個getInstance **總是**返回一個**新的**實例 –

回答

4

你的單身人士是不正確的。 更正確的版本:

class Singleton 
{ 
    private static Singleton singleton = null; 
    private Singleton(){} 
    public static Singleton getInstance() 
    { 
     if (singleton!=null) 
     { 
      return singleton; 
     } 
     return (singleton = new Singleton()); //here is 
    } 
    public string Message{get; set;} 
} 

而且很好的解決方案:

class Singleton 
{ 
    private static Lazy<Singleton> singleton = new Lazy<Singleton>(()=> new Singleton()); 
    private Singleton() { } 
    public static Singleton getInstance() 
    { 
     return singleton.Value; 
    } 
    public string Message { get; set; } 
} 

它與線程safity和延遲初始化沒有問題。

默認情況下,Lazy類的所有公共和受保護成員都是 線程安全並可以從多個線程同時使用。這些 線程安全保證可以使用參數傳遞給類型的構造函數,並可以根據實例 進行選擇性刪除。

+0

請問你可以描述它是如何安全的線程? – Jagdish

+0

@Jagdish由設計懶惰 .Value實現爲線程安全。閱讀更多:https://msdn.microsoft.com/en-us/library/dd642331(v=vs.110).aspx – Backs

+0

好吧,我完全理解謝謝@Backs。但如果你不介意,我可以問你另一個問題嗎?我們如何才能打破第一個單線程類的多線程 – Jagdish

4

你的單例執行是不正確的。
Singleton被設計爲一直只允許沒有或一個實例。
這是你出了問題:

public static Singleton getInstance() 
{ 
    // "singleton" will always be null. 
    if (singleton != null) 
    { 
     return singleton; 
    } 

    // Always returns new instance rather than existing one. 
    return new Singleton(); 
} 

要解決它,你應該寫:

public static Singleton getInstance() 
{ 
    // Return the instance we might have stored earlier. 
    if (singleton != null) 
     return singleton; 

    // Now we store the only instance that will ever be created. 
    singleton = new Singleton(); 
    return singleton; 
} 

注意,如果在並行多次調用這不是線程安全的。

作爲一種資源,我可以推薦喬恩斯基特的帖子:
http://csharpindepth.com/Articles/General/Singleton.aspx

他explaines六種不同的解決方案(包括線程安全和懶惰(T)),以Singleton模式以及如何將它們編碼。

1

單例類的兩個實例是否具有相同的屬性值?

您的問題的答案是肯定的,它們具有相同的屬性值。 重要的是明白爲什麼,而原因是什麼是單身的核心。那麼,爲什麼?:

因爲您將兩個引用與兩個實例混淆。

沒有兩個實例,singleton類總是有一個沒有或一個實例。

在代碼中,單變量和singleton1變量指向兩個相同的對象,單身,而原因是因爲該方法的getInstance()的實施,很容易理解:

如果方法被第一次調用,然後它爲獨特的時間創建新方法的單例對象。

如果第一次調用方法,它將返回在第一次調用方法時創建的單例對象。

因此,無論您有多少個Singleton類型的變量,您都將只有一個使用新方法創建的單例,即實例,單例實例。

相關問題