【发布时间】:2010-09-05 15:29:52
【问题描述】:
换句话说,这个 Singleton 实现线程安全吗:
public class Singleton
{
private static Singleton instance;
private Singleton() { }
static Singleton()
{
instance = new Singleton();
}
public static Singleton Instance
{
get { return instance; }
}
}
【问题讨论】:
-
它是线程安全的。假设多个线程想要一次获取属性
Instance。其中一个线程将被告知首先运行类型初始化程序(也称为静态构造函数)。同时,所有其他想要读取Instance属性的线程将被锁定,直到类型初始化程序完成。只有在字段初始化程序结束后,才会允许线程获取Instance值。所以没有人可以看到Instance是null。 -
@JeppeStigNielsen 其他线程未锁定。根据我自己的经验,我因此遇到了令人讨厌的错误。保证只有第一个线程会启动静态初始化器或构造器,但随后其他线程将尝试使用静态方法,即使构造过程没有完成。
-
@Narvalex This sample program(在 URL 中编码的源代码)无法重现您描述的问题。也许这取决于您拥有的 CLR 版本?
-
@JeppeStigNielsen 感谢您抽出宝贵时间。你能解释一下为什么here这个字段被覆盖了吗?
-
@Narvalex 使用该代码,大写的
X最终变成-1即使没有线程。这不是线程安全问题。相反,初始化程序x = -1首先运行(它位于代码的较早行,较低的行号)。然后初始化器X = GetX()运行,这使得大写的X等于-1。然后是“显式”静态构造函数,类型初始化器static C() { ... }运行,它只更改小写x。所以毕竟,Main方法(或Other方法)可以继续读取大写的X。它的值将是-1,即使只有一个线程。
标签: c# multithreading singleton