Мандаты модели памяти Java та запись a int
является атомарным: Таким образом, если Вы запишете значение в него (состоящий из 4 байтов) в одном потоке и считаете его в другом, то Вы получите все байты или ни один, но никогда 2 новых байта и 2 старых байта или такой.
Для этого не гарантируют long
. Здесь, запись 0x1122334455667788
к переменному содержанию 0
прежде мог привести к другому чтению потока 0x112233440000000
или 0x0000000055667788
.
Теперь спецификация не передает под мандат ссылки на объект, чтобы быть или интервалом или длинно-размер. Поскольку безопасность типов обосновывает, что я подозреваю, что они, как гарантируют, будут записаны атомарно, но на VM на 64 бита эти ссылки могли быть очень хорошо значениями на 64 бита (просто адреса памяти).
Теперь вот мои вопросы:
С уважением, Steffen
См. раздел 17.7 JLS: Неатомарная обработка двойных и длинных
Для целей модели памяти языка программирования Java, однократная запись в энергонезависимую длинную или двойное значение обрабатывается как две отдельные записи : по одной в каждую 32-битную половину. Это может привести к ситуации , когда поток видит первые 32 бита 64-битного значения при одной записи, а вторые 32 бита - при другой записи.
Запись и чтение изменчивых длинных и двойных значений всегда атомарны.
Запись и чтение ссылок всегда атомарны, независимо от , реализованы ли они как 32-битные или 64-битные значения.
В некоторых реализациях может оказаться удобным разделить одно действие записи для 64-битного длинного или двойного значения на два действия записи для смежных 32-битных значений. Для эффективности это поведение зависит от реализации; реализация виртуальной машины Java может выполнять запись в длинные и двойные значения атомарно или двумя частями.
Реализациям виртуальной машины Java рекомендуется избегать разделения 64-битных значений там, где это возможно. Программистам рекомендуется объявлять общие 64-битные значения как изменчивые или правильно синхронизировать свои программы , чтобы избежать возможных осложнений.
(Курсив добавлен)
AtomicReference
Если вы хотите координировать старые и новые значения или хотите конкретных эффектов памяти , используйте класс AtomicReference
.
Например, AtomicReference :: getAndSet
возвращает старое значение при атомарной установке нового значения, что исключает возможность вмешательства другого потока между двумя этапами. Использует семантику энергозависимой
памяти .