Пишет ссылку, атомарную на VMs на 64 бита

Мандаты модели памяти Java та запись a int является атомарным: Таким образом, если Вы запишете значение в него (состоящий из 4 байтов) в одном потоке и считаете его в другом, то Вы получите все байты или ни один, но никогда 2 новых байта и 2 старых байта или такой.

Для этого не гарантируют long. Здесь, запись 0x1122334455667788 к переменному содержанию 0 прежде мог привести к другому чтению потока 0x112233440000000 или 0x0000000055667788.

Теперь спецификация не передает под мандат ссылки на объект, чтобы быть или интервалом или длинно-размер. Поскольку безопасность типов обосновывает, что я подозреваю, что они, как гарантируют, будут записаны атомарно, но на VM на 64 бита эти ссылки могли быть очень хорошо значениями на 64 бита (просто адреса памяти).

Теперь вот мои вопросы:

  • Там какие-либо спецификации модели памяти покрывают это (что я не нашел)?
  • Подозреваемый длинных записей должен быть атомарным на VMs на 64 бита?
  • VMs вынуждены отобразить ссылки на 32 бита?

С уважением, Steffen

46
задан xav 29 August 2014 в 21:25
поделиться

1 ответ

Чтение / запись ссылки всегда атомарные

См. раздел 17.7 JLS: Неатомарная обработка двойных и длинных

Для целей модели памяти языка программирования Java, однократная запись в энергонезависимую длинную или двойное значение обрабатывается как две отдельные записи : по одной в каждую 32-битную половину. Это может привести к ситуации , когда поток видит первые 32 бита 64-битного значения при одной записи, а вторые 32 бита - при другой записи.

Запись и чтение изменчивых длинных и двойных значений всегда атомарны.

Запись и чтение ссылок всегда атомарны, независимо от , реализованы ли они как 32-битные или 64-битные значения.

В некоторых реализациях может оказаться удобным разделить одно действие записи для 64-битного длинного или двойного значения на два действия записи для смежных 32-битных значений. Для эффективности это поведение зависит от реализации; реализация виртуальной машины Java может выполнять запись в длинные и двойные значения атомарно или двумя частями.

Реализациям виртуальной машины Java рекомендуется избегать разделения 64-битных значений там, где это возможно. Программистам рекомендуется объявлять общие 64-битные значения как изменчивые или правильно синхронизировать свои программы , чтобы избежать возможных осложнений.

(Курсив добавлен)

AtomicReference

Если вы хотите координировать старые и новые значения или хотите конкретных эффектов памяти , используйте класс AtomicReference .

Например, AtomicReference :: getAndSet возвращает старое значение при атомарной установке нового значения, что исключает возможность вмешательства другого потока между двумя этапами. Использует семантику энергозависимой памяти .

57
ответ дан 26 November 2019 в 20:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: