我有以下代码,这让我很困惑。问题是,当静态字段 abc 将由 CLR 初始化时,它将是类 ABC 的实例化,这将进一步实例化类 XYZ。我的困惑是,在多线程环境中,在线程对类程序及其成员执行任何操作之前,CLR 已经初始化了字段 abc,这意味着任何尝试运行 DoSomething() 方法的线程都必须共享 abc 字段(这也是 ABC 的一个实例)。这是否意味着类 XYZ 将只实例化一次,因为 CLR 只初始化了一次 abc 字段,它是一个共享字段。
public class XYZ
{
public XYZ(string nameOfClass)
{
Console.WriteLine("XYZ ctor ran");
}
}
public class ABC
{
private XYZ xyz = null;
public ABC(string nameOfClass)
{
xyz = new XYZ(nameOfClass);
}
public void DoSomething()
{
Console.WriteLine("DoSomething Ran");
}
}
public class SomeClass
{
static ABC abc = new ABC("Program");
public void Helper()
{
abc.DoSomething();
}
}
public class Program
{
static void Main()
{
SomeClass sc = new SomeClass();
SomeClass sc2 = new SomeClass();
for (int i = 0; i < 20; i++)
{
new Thread(sc.Helper).Start();
}
sc2.Helper();
}
}
这是否意味着类 XYZ 将只实例化一次,因为 CLR 只初始化了一次 abc 字段,它是一个共享字段。
是的。 只有一个XYZ
实例,因为只有一个ABC
实例。
我要指出的是,您发布的代码都没有显示任何线程不安全的代码,因此不清楚您的担忧是什么。 您可能有多个线程同时执行DoSomething
。
静态字段在第一次访问类时初始化。请参阅 MSDN
类在其类构造函数(静态 C#中的构造函数,Visual Basic中的共享子新增功能)已完成 运行。防止在不是 初始化后,公共语言运行库会阻止来自其他语言的所有调用 类的静态成员的线程(视觉对象中的共享成员 基本),直到类构造函数完成运行。