编程语言
首页 > 编程语言> > c# – 不带锁定的double [] []元素的并发修改

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