Что означает «ложный сбой» в AtomicInteger weakCompareAndSet?

У класса Java AtomicInteger есть метод -

boolean weakCompareAndSet(int expect,int update)

Его документация говорит:

Может неуспешно провалиться.

Что здесь означает «неудачный отказ»?

10.12.2008 07:44:32
Ложное означает «фальшивый» или «недостоверный». Так что я думаю, что «внезапно потерпеть неудачу» означает потерпеть неудачу таким образом, чтобы это не выглядело как неудача. См. Также использование термина docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html , где случайный сбой ссылается на сценарий, в котором возникает ошибка, но какой-то несовместимый веб-сервер по-прежнему возвращает HTTP 200 (OK),
flow2k 21.05.2018 19:35:22
4 ОТВЕТА

Это означает, что он может вернуть false (и не будет устанавливать новое значение), даже если он в настоящее время содержит ожидаемое значение.

Другими словами, метод может ничего не делать и возвращать false без видимой причины ...
Существуют архитектуры ЦП, в которых это может иметь преимущество в производительности по сравнению с сильным CompareAndSet().


Немного конкретнее о том, почему что-то подобное может произойти.

Некоторые архитектуры (например, более новые ARM) реализуют операции CAS с использованием набора инструкций Load Linked (LL) / Store Conditional (SC). Инструкция LL загружает значение в ячейку памяти и где-то «запоминает» адрес. Инструкция SC сохраняет значение в этой ячейке памяти, если значение по запомненному адресу не было изменено. Аппаратные средства могут полагать, что расположение было изменено, даже если это, по-видимому, не было по ряду возможных причин (и причины могут различаться в зависимости от архитектуры ЦП):

  1. местоположение может быть написано с тем же значением
  2. разрешение просматриваемых адресов может быть не единственным интересующим местом памяти (например, строки кэша). Запись в другое местоположение, которое находится «рядом», может привести к тому, что аппаратное обеспечение пометит рассматриваемый адрес как «грязный».
  3. ряд других причин, которые могут привести к потере ЦП сохраненного состояния инструкции LL - переключение контекста, очистка кэша или изменения таблицы страниц.
6
10.12.2008 16:18:31

неосторожно: без видимой причины

Согласно atomicпакету Javadoc:

Атомарные классы также поддерживают метод weakCompareAndSet, который имеет ограниченную применимость.

На некоторых платформах слабая версия может быть более эффективной, чем compareAndSet в обычном случае, но отличается тем, что любой заданный вызов метода weakCompareAndSet может возвращать ложное значение (то есть без видимой причины ).

Ложный возврат означает только то, что операция может быть повторена при желании, полагаясь на гарантию того, что повторный вызов, когда переменная содержит Ожидаемое значение и никакой другой поток также не пытается установить переменную, в конечном итоге завершится успешно.
(Такие ложные сбои могут, например, быть вызваны эффектами конфликта памяти, которые не связаны с тем, равны ли ожидаемые и текущие значения.)

Кроме того, weakCompareAndSet не предоставляет гарантий упорядочения, которые обычно необходимы для управления синхронизацией.


Согласно этому потоку , это не столько из-за «оборудования / ОС», сколько из-за алгоритма, который используется weakCompareAndSet:

weakCompareAndSet атомарно устанавливает значение в данное обновленное значение, если текущее значение == ожидаемое значение . Может неуспешно провалиться.

В отличие от compareAndSet () и других операций в AtomicX, операция weakCompareAndSet () не создает никаких упорядочений, предшествующих событию .

Таким образом, тот факт, что поток видит обновление AtomicX, вызванное weakCompareAndSet, не означает, что он должным образом синхронизирован с операциями, которые произошли до уязвимости уязвимого узла ().

Вы, вероятно, не хотите использовать этот метод, но вместо этого следует просто использовать compareAndSet; поскольку есть несколько случаев, когда weakCompareAndSet работает быстрее, чем CompareAndSet, и в ряде случаев попытка оптимизировать код с помощью weakCompareAndSet, а не CompareAndSet, привнесет в код незаметные и трудные для воспроизведения ошибки синхронизации.


Примечание по поводу заказов до и после :

Модель памяти Java (JMM) определяет условия, при которых поток, читающий переменную, гарантированно видит результаты записи в другом потоке.

JMM определяет порядок операций программы, которая называется случаем раньше.

Порядок случайностей перед потоками создается только путем синхронизации с общей блокировкой или доступа к общей изменчивой переменной.

При отсутствии порядка «происходит до» у платформы Java есть широкие возможности для задержки или изменения порядка, в котором записи в одном потоке становятся видимыми для чтения той же переменной в другом.

18
10.12.2008 15:25:15

Но почему такое вообще допускается? Это потому, что аппаратное обеспечение / ОС под ним глючит? Или за этим стоит какая-то веская техническая причина?

0
10.12.2008 13:18:43
Только что добавили техническую причину, связанную с заказами «до и после» в JMM (модель памяти Java)
VonC 10.12.2008 15:25:53

Хорошим вариантом использования для weakCompareAndSet являются счетчики производительности - нет необходимости в упорядочении, высокая скорость обновлений (так что упорядочение плохо сказывается на плохо упорядоченных системах), но при высоких нагрузках отсчет не сбрасывается (плотно перегруженные счетчики перфорации могут сбросить 99% от всех). рассчитывает, по существу оставляя значение счетчиков по отношению к случайным счетчикам неконтролируемым).

6
13.12.2013 21:59:13