每个人都说不可变对象(immutable对象)是线程安全的,但这是为什么呢?
以在多核 CPU 上运行以下场景为例:
0x100
并且缓存在Core 1的L1/L2缓存中; 0x100
可用于新对象; 0x100
; 0x100
读取它. 在这种情况下,当核心 1 请求位置
0x100
的值时它是否有可能从其 L1/L2 缓存中读取过时的数据?我的直觉说这里仍然需要一个内存门来确保 Core 1 读取正确的数据。上述分析是否正确,是否需要内存门,还是我遗漏了什么?
更新:
我在这里描述的情况是每次 GC 执行收集时发生的情况的更复杂版本。当 GC 收集时,内存被重新排序。这意味着对象所在的物理位置发生了变化,L1/L2 必须失效。大致相同的情况适用于上面的示例。
由于可以合理地期望 .NET 确保在重新排序内存后,不同的内核看到正确的内存状态,因此上述情况也不会成为问题。
最佳答案
在您的场景中,对象的不变性并不是真正的问题。相反,您的描述问题围绕着指向该对象的引用、列表或其他系统。它当然需要某种技术来确保旧对象不再可用于可能试图访问它的线程。
不可变对象(immutable对象)的线程安全性的真正意义在于您不需要编写一堆代码来产生线程安全性。而是框架、操作系统、CPU(以及其他任何东西)为您完成工作。
关于.net - 不可变对象(immutable对象)的线程安全性如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5433579/