2014-11-21 87 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