Можно ли условно обновить nullable long без блокировки? - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть long? startTime для хранения времени начала.

У меня есть несколько потоков с не async методами обновления startTime, и есть другой async метод в отдельном потоке, который только когда-либо читал этозначение.Методы, которые обновляют значение, делают так, как показано ниже:

if (startTime == null || (newValue != 0 && newValue < startTime))
{
    startTime = newValue;
}

Проблема заключается в том, что потоки модуля записи обновляют startTime с очень очень высокой частотой, вызывая много конфликтов для блокировки.Итак, есть ли способ, которым я могу сделать это без блокировки (или лучший механизм блокировки по сравнению с обычной блокировкой)?

Я думаю об использовании Interlocked, но из-за предложения if, я думаю,это не правильно?

РЕДАКТИРОВАТЬ: я могу изменить его на необнуляемый при необходимости.

1 Ответ

0 голосов
/ 29 ноября 2018

С конца вопроса:

РЕДАКТИРОВАТЬ: я могу изменить его на необнуляемый при необходимости.

Для не обнуляемых long, вынужен цикл проверки и обновления (что-то вроде этого):

var current = Interlocked.Read(ref startTime);
while(current > newValue)
{
  var other = Interlocked.CompareExchange(ref startTime, newValue, current);
  if(other==current) break;
  current = other;
}

Вы можете сделать ваши условия while произвольно сложными, они фактически станут вашей if проверкой.Вам также может потребоваться / необходимо пересчитать newValue внутри цикла.

Interlocked.Read возвращает начальное значение.Interlocked.CompareExchange делает «если значение остается таким же, как когда я последний раз читал значение, зафиксирую свое изменение», а также получает новое текущее значение, если значение изменилось.

Другие вопросы, которые следует учитывать - делатьВы действительно нуждаетесь в этом значении «времени начала», или же на его месте может стоять простое увеличивающееся целое число?Это будет Interlocked.Increment без циклов и блокировок, поэтому стоит подумать о том, велика ли здесь конкуренция при записи, если вы можете соответствующим образом изменить другие части кода.

...