Threading.Volatile.Read(Int64) 和 Threading.Interlocked.Read(Int64) 的区别?

Difference between Threading.Volatile.Read(Int64) and Threading.Interlocked.Read(Int64)?

.NET系统的Read(Int64)方法有什么区别classes System.Threading.Volatile and System.Threading.Interlocked?

具体来说,它们在 (a) 原子性和 (b) 内存排序方面各自的保证/行为是什么。

请注意,这是关于 Volatile class, 而不是 volatile(小写)关键字。


MS 文档状态:

Volatile.Read Method

Reads the value of a field. On systems that require it, inserts a memory barrier that prevents the processor from reordering memory operations as follows: If a read or write appears after this method in the code, the processor cannot move it before this method.

...

Returns Int64

The value that was read. This value is the latest written by any processor in the computer, regardless of the number of processors or the state of processor cache.

对比

Interlocked.Read(Int64) Method

Returns a 64-bit value, loaded as an atomic operation.

特别令人困惑的是 Volatile 文档没有讨论原子性,Interlocked 文档没有讨论排序/内存障碍。

旁注:仅供参考:我更熟悉 C++ atomic API,其中原子操作始终还指定内存排序语义。


(and transitive links) helpfully provided by 很好地解释了 volatile-as-in-memory-barrier 和 atomic-as-in-no-torn-reads 的差异/正交性,但他们没有解释如何这两个概念适用于这两个 classes.

Interlocked.Read translates into a CompareExchange operation:

public static long Read(ref long location)
{
    return Interlocked.CompareExchange(ref location, 0, 0);
}

因此它具有 CompareExchange 的所有优点:

  • 完全内存屏障
  • 原子性
另一方面,

Volatile.Read 仅获得语义。它可以帮助您确保读取操作的执行顺序,而无需任何原子性或新鲜度保证。