Написание длинных и двойных не атомарно в Java?

Чтение и запись одной переменной является атомарным (языковая гарантия!), Если только переменная не имеет тип long или double.

Я читал слайды курса и нашел, что написано. Класс был о параллелизме.

Может кто-нибудь объяснить мне, почему написание long или double не является атомарной операцией? Это действительно застало меня врасплох.

7 ответов

Решение

Это не атомарно, потому что это многошаговая операция на уровне машинного кода. То есть long и double больше длины слова процессора.

Просто чтобы прояснить ситуацию для Java, двойные и длинные не читаются или записываются атомарно, если они не объявлены volatile

JLS - Неатомарное лечение двойной и длинной

Java long и double не атомарны на 32-битных машинах, но атомарны на 64-битных машинах с некоторыми из 64-битных JVM. почему это зависит от длины бит машины? Потому что 32-битной машине нужны две записи для длинной (так как long для 64-битной). Прочитайте это для подробной информации.

Многие программисты должны прочитать это утверждение в "3.1.2. Неатомарные 64-битные операции" на практике в java-параллелизме. Я сослался на последнюю версию JLS 17.7. Неатомарная обработка двойная и длинная. Они до сих пор нигде не утверждают, что 64-битная jVM в наши дни является нормой. Таким образом, 64-битные операции разбиты на 32-битные операции, которые нарушают атомарность и опасны для использования в многопоточной среде до тех пор, пока не будут объявлены энергозависимыми. Длинные и двойные 64-битные в Java. Таким образом, операции записи и чтения не являются атомарными в Java.

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

Прочитать ответ от maaartinus @ Какие операции в Java считаются атомарными?
Прочитайте ответ Джона Скита @ Когда примитивные типы данных не являются поточно-ориентированными в Java?

В соответствии с JLS вы можете сделать операции чтения и записи двойными и длинными, чтобы они были атомарными, объявив их как энергозависимые. Но это не гарантирует, что ++ будет атомарным. Это требует пакета concurrent.atomic.
Прочтите этот ответ от Луи Вассермана.

Также этот блог и комментарии.

Операция с атомарной переменной означает, что любой поток может читать / писать из / в него без мусора.

Не long/ doubleчтение / запись предназначены для x32 и некоторых x64 из-за аппаратных ограничений. Если volatile используется делает это / добавляет к нему atomic

[Атомарность]

Другие вопросы по тегам