我经常听说在 .NET 2.0 内存模型中,写入总是使用释放栅栏。这是真的?这是否意味着即使没有显式的内存屏障或锁,也不可能在与创建对象不同的线程上观察到部分构造的对象(仅考虑引用类型)?我显然排除了构造函数泄漏this
引用的情况。
例如,假设我们有不可变的引用类型:
public class Person
{
public string Name { get; private set; }
public int Age { get; private set; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
是否可以使用以下代码观察除“John 20”和“Jack 21”以外的任何输出,例如“null 20”或“Jack 0”?
// We could make this volatile to freshen the read, but I don't want
// to complicate the core of the question.
private Person person;
private void Thread1()
{
while (true)
{
var personCopy = person;
if (personCopy != null)
Console.WriteLine(personCopy.Name + " " + personCopy.Age);
}
}
private void Thread2()
{
var random = new Random();
while (true)
{
person = random.Next(2) == 0
? new Person("John", 20)
: new Person("Jack", 21);
}
}
这是否也意味着我可以使所有共享字段都具有深度不可变的引用类型volatile
,并且(在大多数情况下)继续我的工作?