Является ли ConcurrentSkipListMap.compute () безопасным для относительных обновлений? - PullRequest
0 голосов
/ 15 ноября 2018

Javadoc для ConcurrentSkipListMap.compute (K, BiFunction) сообщает:

Пытается вычислить сопоставление для указанного ключа и его текущего сопоставленного значения (или ноль, если существует)нет текущего отображения).Функция НЕ гарантированно применяется один раз атомарно.

Я понимаю, что функция может быть вызвана несколько раз, но что означает "один раз атомно"?

В частности,безопасно ли вызывать функцию X = X + 1 без многократного увеличения значения карты?

1 Ответ

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

Это говорит о том, что:

  • функция может вызываться более одного раза, а
  • эти звонки могут перекрываться во времени; т.е. если несколько потоков одновременно вызывают compute.

Другими словами, не ожидайте поведения atomic в способе, которым ссылка на функцию вызывается compute.


В частности, безопасно ли для функции вызывать X = X + 1 без многократного увеличения значения карты?

Это зависит от того, что означает «вызвать X = X + 1». (Вы не включили четкий пример ....)

  • Если x = x + 1 означает, что вы просто пытаетесь увеличить значение карты, то:

    • Один вызов compute приведет только к одному «приращению» из-за определения в compute в ConcurrentMap.

    • Но при возврате из compute значение могло быть увеличено более одного раза, потому что другой поток делал то же самое одновременно.

  • Если x = x + 1 относится к побочному эффекту ссылки на метод, тогда все ставки выключены:

    • Это могло произойти несколько раз.
    • Если ссылка на ваш метод не синхронизирована должным образом, и так далее, возможны всевозможные неприятные эффекты. Спецификация подразумевает, что вызов compute не будет синхронизироваться извне или вызывать ссылку на метод в мьютексе или что-то в этом роде. Применяются нормальные правила параллелизма / памяти ...
...