来自MSDN的一句话
在所有硬件平台上,分配此类型的实例都不是线程安全的,因为该实例的二进制表示可能太大而无法在单个原子操作中分配。
这是否意味着像Itianium或x86-64这样的64位处理器也是线程安全的?
例如:
long data = GetData();
// some parallel task on data
可能会有问题吗?
来自MSDN的一句话
在所有硬件平台上,分配此类型的实例都不是线程安全的,因为该实例的二进制表示可能太大而无法在单个原子操作中分配。
这是否意味着像Itianium或x86-64这样的64位处理器也是线程安全的?
例如:
long data = GetData();
// some parallel task on data
可能会有问题吗?
Decimal
和Double
类型也对线程安全有此免责声明。如果在对齐的内存地址上执行的内存加载/存储操作不大于本地机器指针大小,那么它们被认为是原子性的。
这意味着,64位平台上对齐的内存地址进行64位的加载/存储操作将是原子性的,但在32位平台上不会是原子性的。
现代处理器提供了一组特殊的指令(在 .Net 中,其中大多数通过 Interlocked
类公开),允许实现对大于机器本地指针大小的载入/存储操作的原子性(32位处理器上的64位操作和64位处理器上的128位操作。后者未在 Interlocked
类中公开,但可在本机代码中使用)。
有关详细信息,请参见 Joe Duffy 的文章:Thread-safety, torn reads, and the like。
如果你的data
变量被不同线程的代码直接访问,那就会出现问题。
他们并没有对任何特定系统做出保证,所以为了安全起见,我会假设在x64系统和x86系统上都不是线程安全的,尽管我怀疑他们真正考虑的是在智能手机上运行的紧凑框架之类的地方。
我会偏向于安全起见并且假设不行。
请注意之前的问题。对于 Int64 的原子赋值,你应该考虑使用 Interlocked 类。
还可以查看这个链接以获取更详细的分析。特别是,请查看标有“原子性和 Interlocked”的部分。
Int64
不能保证是原子性的,但这并不排除它在某些情况下具有原子性。换句话说,在64位系统上,Int64
将是原子性的。当然,这并不意味着它一定是线程安全的。除了原子性之外,还有其他与线程安全相关的问题。例如,为了防止陈旧问题,您必须使用适当的内存屏障指令(volatile
、Thread.VolatileWrite
等)。