我在C#中有以下内容:
private double _x;
private bool _xCalculated;
private double GetX() {
if (!_xCalculated) {
_x = ... // some relatively expensive calculation
_xCalculated = true;
}
return _x;
}
我的问题是,这是线程安全的吗?据我所知,最糟糕的结果是两个或多个线程同时进入此方法并多次计算_x
,但对于此类的任何实例,结果保证相同,这不是一个特别大的问题。
我对此的理解是否正确?
答案 0 :(得分:6)
一些观察结果:
虽然我认为x86 memory ordering guarantees使这个安全,但我并不完全确定。最近.net的内存排序保证已得到加强(我认为在.net 4中)以匹配x86的保证。
Memory Model in .net
More on memory ordering
这表明商店没有在.net中重新排序,我认为这意味着您的代码是安全的。但无锁编程很难,所以我可能会忽略一些微妙的问题。也许if子句中的读取可能会导致问题。
我建议不要使用此代码,除非您是线程专家并且确实需要性能。否则只需使用像锁一样更明确的东西。如果他们没有参与竞争,锁定并不昂贵。
答案 1 :(得分:2)
它不是线程安全的。是的,你的理解是正确的。您可以使用lock()
语句使其成为线程安全的。
http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.71).aspx
private object objLock = new object();
private double GetX() {
lock(objLock) {
if (!_xCalculated) {
_x = ... // some relatively expensive calculation
_xCalculated = true;
}
}
return _x;
}
答案 2 :(得分:1)
这取决于平台,我不认为按照其规范使用.NET内存模型是安全的,但我认为在当前的Microsoft CLR上它是可以的。问题在于允许CPU 重新排序内存写入的范围。
有人可以提供规范的详细链接......