.NET线程安全缓存结果

der*_*dex 6 .net multithreading

我在C#中有以下内容:

private double _x;
private bool _xCalculated;

private double GetX() {
    if (!_xCalculated) {
        _x = ... // some relatively expensive calculation
        _xCalculated = true;
    }

    return _x;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,这是线程安全的吗?据我所知,最糟糕的结果是两个或多个线程同时进入此方法并计算_x多次,但结果保证对于此类的任何实例都是相同的,因此不是特别大的问题.

我对此的理解是否正确?

Cod*_*aos 6

一些观察:

  1. 进入双重的商店可能不是原子的
  2. 对bool的写入应该是原子的
  3. 根据CPU架构,可能会重新排序内存操作
  4. 如果没有重新排序,代码应该工作

虽然我认为x86内存排序保证使这个安全,但我并不完全确定.最近(我认为.net 4)强化了.net的内存排序保证,以匹配x86的保证.

.net中的内存模型
关于内存排序的更多信息
这说明商店没有在.net中重新排序,我认为这意味着您的代码是安全的.但无锁编程很难,所以我可能会忽略一些微妙的问题.也许if子句中的读取可能会导致问题.

我建议不要使用此代码,除非您是线程专家并且确实需要性能.否则只需使用像锁一样更明确的东西.如果他们没有竞争,锁定并不昂贵.