我正在实现单例模式,并且需要初始化是线程安全的。
我已经看到了几种方法,比如使用双重检查锁实现或其他技术(即: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;
}
}
}
答案 0 :(得分:3)
是的,这是线程安全的 - 尽管它不是正常的单例模式,因为没有你的类本身的实例。它更像是一个单一价值的工厂模式&#34;。该类将初始化一次(假设没有任何东西用反射调用类型初始值设定项),并且当它在一个线程中初始化时,请求TracerMock
的任何其他线程都必须等待。
通过删除方法,您的代码也可以简化:
public static class SharedTracerMock
{
private static readonly Mock<ITracer> tracerMock = new Mock<ITracer>();
public static Mock<ITracer> TracerMock { get { return tracerMock; } }
}
请注意,我也已将该字段设为只读,这有助于提高清晰度。我通常也会像这样在一条线上粘贴琐碎的吸气剂,以避免大量的线条只需要支撑(一行返回语句的7行代码就像是矫枉过正)。
在C#6中,使用只读自动实现的属性可以进一步简化:
public static class SharedTracerMock
{
public static Mock<ITracer> TracerMock { get; } = new Mock<ITracer>();
}
当然,仅仅因为这个属性是线程安全的并不意味着它返回引用的对象将是线程安全的......不知道{{1}我们真的无法说出来。