.net - 不可变对象(immutable对象)的线程安全性如何?

标签 .net multithreading concurrency immutability

每个人都说不可变对象(immutable对象)是线程安全的,但这是为什么呢?

以在多核 CPU 上运行以下场景为例:

  • 核心 1 在内存位置读取一个对象 0x100并且缓存在Core 1的L1/L2缓存中;
  • GC 在那个内存位置收集这个对象,因为它已经符合条件并且0x100可用于新对象;
  • Core 2 分配一个(不可变)对象,该对象位于地址 0x100 ;
  • 核心 1 获得对这个新对象的引用并在内存位置 0x100 读取它.

  • 在这种情况下,当核心 1 请求位置 0x100 的值时它是否有可能从其 L1/L2 缓存中读取过时的数据?我的直觉说这里仍然需要一个内存门来确保 Core 1 读取正确的数据。

    上述分析是否正确,是否需要内存门,还是我遗漏了什么?

    更新:

    我在这里描述的情况是每次 GC 执行收集时发生的情况的更复杂版本。当 GC 收集时,内存被重新排序。这意味着对象所在的物理位置发生了变化,L1/L2 必须失效。大致相同的情况适用于上面的示例。

    由于可以合理地期望 .NET 确保在重新排序内存后,不同的内核看到正确的内存状态,因此上述情况也不会成为问题。

    最佳答案

    在您的场景中,对象的不变性并不是真正的问题。相反,您的描述问题围绕着指向该对象的引用、列表或其他系统。它当然需要某种技术来确保旧对象不再可用于可能试图访问它的线程。

    不可变对象(immutable对象)的线程安全性的真正意义在于您不需要编写一堆代码来产生线程安全性。而是框架、操作系统、CPU(以及其他任何东西)为您完成工作。

    关于.net - 不可变对象(immutable对象)的线程安全性如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5433579/

    相关文章:

    android - 帮助为应用程序选择云服务器

    java - 迭代并发Hashmap

    java - 如何返回已在 4 个不同线程中编辑过的变量的一个实例?

    mysql - 获取给定时间范围内的 MySQL 服务器负载

    c# - MSACCESS DateTIme SQL 查询

    .net - 用于性能基准测试的 Visual Studio 加载项

    c# - 当原始请求有内容时如何克隆 HttpRequestMessage?

    c# - 检测特定线程内无事件的时间段

    Java ExecutorService 暂停/恢复特定线程

    Python 多处理限制。仅限 3 个数据库连接