在C#中可以预先构建一个构造函数吗?
例如,考虑代码:
public class A
{
public bool ready = true;
public A()
{
ready = false; // Point #1
// Other initialization stuff
ready = true; // Point #2
}
}
在代码的其他地方,两个线程可以访问类型A的变量,第一个线程调用在第1点被抢占的构造函数.然后第二个线程测试准备,并发现它仍然是真的,因此它做坏事.
这种情况是否可行?
进一步来说:
>可以预先构建一个构造函数吗?
>如果是这样,这是否意味着应该有同步代码,如锁在构造函数?
>构造函数退出之后,正在构造的对象是否只分配给共享变量,从而完全避免了这个问题?
解决方法
我不认为接受的答案是正确的. Igor Ostrovsky的“
The C# Memory Model in Theory and Practice”(
part 2 here)彻底解释了这些问题,其中一个例子说明了你正在问的问题.
它给出代码
class BoxedInt2
{
public readonly int _value = 42;
void PrintValue()
{
Console.WriteLine(_value);
}
}
class Tester
{
BoxedInt2 _Box = null;
public void Set() {
_Box = new BoxedInt2();
}
public void Print() {
var b = _Box;
if (b != null) b.PrintValue();
}
}
并注意:
Because the BoxedInt instance was incorrectly published (through a non-volatile field,_Box),the thread that calls Print may observe a partially constructed object! Again,making the _Box field volatile would fix the issue.
我强烈地鼓励阅读整篇文章,这是非常有用的阅读.