安全读取long 内容的最快方法,其元素同时更改

当你有一个

long[] myArray = new long[256]; 

其项目由多个线程使用更改

 Interlocked.Increment(ref myArray[x]) 

肯定不可能在某个时间点获取myArray的快照,因为同时存在非锁定写入,所以我不是想要得到它。

那么我真的需要Volatile.Read的每一个元素来获取过去某个时刻的所有值的副本吗?

 long[] copy = new long[256]; for (int i = 0; i < 256; i++) copy[i] = Volatile.Read(ref myArray[i]); 

由于我对某个时间点的快照不感兴趣,过时的值不是问题,但由于64位非易失性读取不是primefaces的,我担心以下可能会给我一个预增量的一半long,和后增量的一半,可能会给出一个从未存在于数组中的值。

 long[] copy = new long[256]; for (int i = 0; i < 256; i++) copy[i] = myArray[i]; 

那么Volatile.Read变种是正确的选择,因为我不想使用任何锁定?

如果陈旧值对您来说不是问题,而您只需要primefaces读取(不是有序的),那么在x64上您可以使用普通读取而不是Volatile.Read 。 它在ARM系统上是有益的,因为它们是用DMB实现的,因此易失性读/写是相当重要的。

重要事项根据这 一点 ,您需要(构建和)以64位模式运行.Net程序,以实现此目的:

如果您在64位版本的CLR中的64位操作系统上运行C#代码,则64位双精度和长整数的读写也保证是primefaces的

在C#中没有像primefaces类型这样的东西(你可能知道),只有primefaces操作。

抖动和/或处理器可以决定重新排序指令,因此您可以正确地假设您需要

  • 使用lock 序列化访问
  • 使用Interlocked类进行写入(在某些情况下读取)
  • 声明变量volatile (尽管它在64位类型上不可用,并且不适用于数组)
  • 或者在你的情况下使用Volatile.Read如果你不介意陈旧的值。

要回答您的问题,并且没有看到您的代码或您如何处理此问题,您的方法似乎是正确的解决方案

Volatile.Read方法

读取字段的值。 在需要它的系统上,插入一个内存屏障,阻止处理器重新排序内存操作,如下所示:如果在代码中此方法后出现读取或写入,则处理器无法在此方法之前移动它