c# – 不带锁定的double [] []元素的并发修改
作者:互联网
我有一个锯齿状的double [] []数组,可以由多个线程同时修改.我想让它成为线程安全的,但如果可能的话,没有锁.线程可能很好地针对阵列中的相同元素,这就是出现整个问题的原因.我找到了使用Interlocked.CompareExchange方法以原子方式递增double值的代码:Why is there no overload of Interlocked.Add that accepts Doubles as parameters?
我的问题是:如果Interlocked.CompareExchange中存在锯齿状数组引用,它会保持原子状态吗?非常感谢您的见解.
举个例子:
public class Example
{
double[][] items;
public void AddToItem(int i, int j, double addendum)
{
double newCurrentValue = items[i][j];
double currentValue;
double newValue;
SpinWait spin = new SpinWait();
while (true) {
currentValue = newCurrentValue;
newValue = currentValue + addendum;
// This is the step of which I am uncertain:
newCurrentValue = Interlocked.CompareExchange(ref items[i][j], newValue, currentValue);
if (newCurrentValue == currentValue) break;
spin.SpinOnce();
}
}
}
解决方法:
是的,它仍然是原子和线程安全的.对同一个单元的任何调用都将传递相同的地址到双精度数.它是否在作为对象上的字段的数组中的细节是无关紧要的.
但是,行:
double newCurrentValue = items[i][j];
不是原子的 – 理论上可以给出一个撕裂的价值(特别是在x86上).在这种情况下,这实际上是正常的,因为在撕裂值场景中它只会碰到循环,算作碰撞,并重做 – 这次使用来自CompareExchange的已知原子值.
标签:c,arrays,multithreading,concurrency,interlocked 来源: https://codeday.me/bug/20190611/1218088.html