.NET 线程安全缓存结果

标签 .net multithreading

我在 C# 中有类似以下内容:

private double _x;
private bool _xCalculated;

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

    return _x;
}

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

我对此的理解是否正确?

最佳答案

一些观察:

  • 存储到 double 可能不是原子的
  • 对 bool 的写入应该是原子的
  • 根据 CPU 架构,内存操作可能会重新排序
  • 如果没有发生重新排序,代码应该可以工作

  • 虽然我认为x86 memory ordering guarantees确保安全,我对此并不完全确定。 .net 的内存排序保证最近得到了加强(我认为在 .net 4 中)以匹配 x86 的保证。

    Memory Model in .net
    More on memory ordering
    这表明商店不会在 .net 中重新排序,我认为这意味着您的代码是安全的。但是无锁编程很难,所以我可能会忽略一些微妙的问题。也许 if 子句中的读取会导致问题。

    我建议不要使用此代码,除非您是线程专家并且真的非常需要性能。否则只需使用更明确的东西,比如锁。如果没有争用,锁就不会那么昂贵。

    关于.NET 线程安全缓存结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4255858/

    相关文章:

    c# - 方法 'ToString"没有重载在转换日期时采用 1 个参数

    c# - 项目 'Projr' 不是最新的。 VS 2017 管理员模式下缺少输出文件 'c:\..\bin\Debug\Projr.dll'

    c# - 使用 Entity Framework 的 Struct 变通方法,Code-First 方法

    c# - 可选的线程安全(线程安全部分仅在条件下)

    multithreading - flatMap future 列表中的 future 正在执行阻塞操作,那么为什么不将代码包含在阻塞{..}中呢?

    c# - 有没有办法阻止 Visual Studio 将线程退出语句打印到输出窗口中?

    c# - 如何在 Winform 中使用多线程?

    java - volatile 关键字有什么用?

    Python:如何终止阻塞线程

    java - 什么是 JaMP,我如何了解它?