У меня есть зубчатый массив double[][]
, который может быть изменен одновременно несколькими потоками. Я хотел бы сделать его потокобезопасным, но, если возможно, без блокировок. Потоки могут хорошо ориентироваться на один и тот же элемент в массиве, поэтому возникает вся проблема. Я нашел код для увеличения значения двойного атомарно используя Interlocked.CompareExchange
метод: 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();
}
}
}
Лично Я бы переименовал 'newCurrentValue' в' oldValue' - это просто сбивает с толку :) –
Вы понимаете, что while() в основном совпадает с использованием SpinLock, но с дополнительной сложностью? – Gusman
@ Гусман вам нужен петля, хотя вам нужно повторить с начала в (редком) случае столкновения –