2014-11-21 41 views
0

我正在實現一個單例模式,並且需要初始化爲線程安全。線程安全Singletion靜態方法初始化

我已經看到了幾種方法來做到這一點,就像使用雙重檢查鎖執行,或其他技術(即:http://csharpindepth.com/articles/general/singleton.aspx

我想知道如果下面的辦法,這是類似的第四個版本在文章中,是線程安全的。我基本上在靜態字段初始值設定項中調用一個方法,該方法創建實例。我不在乎懶惰。謝謝!

public static class SharedTracerMock 
{ 
    private static Mock<ITracer> tracerMock = CreateTracerMock(); 

    private static Mock<ITracer> CreateTracerMock() 
    { 
     tracerMock = new Mock<ITracer>(); 
     return tracerMock; 
    } 

    public static Mock<ITracer> TracerMock 
    { 
     get 
     { 
      return tracerMock; 
     } 
    } 
} 

回答

3

是的,這是線程安全的 - 雖然它不是正常的單例模式,因爲沒有類本身的實例。這更像是一種「單值工廠模式」。該類將被初始化一次(假設沒有用反射調用類型初始值設定項),並且在一個線程中進行初始化時,請求TracerMock的任何其他線程將不得不等待。

你的代碼也可以通過去除雖然方法簡單:

public static class SharedTracerMock 
{ 
    private static readonly Mock<ITracer> tracerMock = new Mock<ITracer>(); 

    public static Mock<ITracer> TracerMock { get { return tracerMock; } } 
} 

請注意,我做了場只讀爲好,這有助於在清晰度方面。我通常會在這樣的一行中粘貼一些簡單的getter,以避免大量帶有大括號的行(對於一個return語句的7行代碼感覺像是矯枉過正)。

在C#6,這可更使用只讀自動實現的屬性簡化:

public static class SharedTracerMock 
{ 
    public static Mock<ITracer> TracerMock { get; } = new Mock<ITracer>(); 
} 

當然,只是因爲這財產是線程安全的,並不意味着對象返回一個參考將是線程安全的...不知道Mock<T>,我們無法真正知道這一點。

+0

非常感謝喬恩,像往常一樣非常有幫助和詳細! – 2014-11-21 07:09:17

+0

c#6部分很不錯 – Disposer 2014-11-21 10:55:49

相關問題