Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Что такое атомный?

Автор вопроса: RoxОтветов: 4

Это две атомарные операции:

int value = 5;
Object obj = new Object();

Но при использовании примитива в качестве параметра метода будет ли это рассматриваться как атомарная операция: public void setValue(int val, Object obj){
this.value = val; // Atomic?
this.obj = obj; // Not atomic?
}

? Копия ссылки на объект не является атомарной, поскольку включает чтение и запись, верно?

Было бы правильно сказать, что единственный способ выполнить атомарную операцию над ссылкой на объект - это объявить ее нулевой или присвоить ей новый объект, например:

Object obj = null;

и

Object obj = new Object();

?

javaatomicityterminology

Ответы

Ответ 1 · рейтинг 4 · PeterMmm

Если бы параметр в приведенном выше методе был ссылкой на объект, то операция не была бы атомарной, верно?

В целом это правильно. Хорошее эмпирическое правило состоит в том, чтобы считать, что атомарности вообще нет, даже с такими примитивами, как:

int b,c;
int a = ++b - c;

только примитивы, но все назначение является потенциальным, а не атомарным.

Если вам нужны атомарные операции, у вас есть разные возможности:

  • синхронизированные блоки
  • неизменяемые объекты
  • определенные библиотеки (java.util.concurrent.atomic)

Ответ 2 · рейтинг 3 · JB Nizet

Когда поток читает значение примитива (кроме long и double) или ссылки на объект, он видит значение, которое он установил в этой переменной, или значение, которое другой поток установил в этой переменной.

Однако, хотя присвоение значения общей переменной в одном потоке является атомарным, это не означает, что все остальные потоки увидят новое значение сразу после этого. Для этого переменная должна быть объявлена ​​volatile. volatile также делает записи в long и double atomic. Однако в этом случае я предпочитаю использовать AtomicXxx (AtomicLong, AtomicBoolean и т. д.).

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

Более того, каждая операция "проверить, затем выполнить" или "прочитать, а затем записать" не является атомарной. Это означает, что эти операции также нуждаются в синхронизации:

a++; // read a, increment value, write value to a
if (a > 0) {a = b;} // check value of a, then assign new value to a.

Каждая операция в вашем вопросе является атомарной. Но в setValue() у вас есть две атомарные операции. Весь вызов setValue не является атомарным.

Ответ 3 · рейтинг 1 · Tim Bender

За JLS!

Когда поток использует значение переменной, получаемое им значение на самом деле является значением, сохраненным в переменной этим потоком или каким-либо другим потоком. Это верно даже в том случае, если программа не содержит кода для правильной синхронизации. Например, если два потока хранят ссылки на разные объекты в одном и том же значении ссылки, переменная впоследствии будет содержать ссылку на тот или иной объект, а не ссылку на какой-то другой объект или поврежденное значение ссылки.

Таким образом, задание является атомарным.

Ответ 4 · Nicholas Jordan

public synchronized void setValue(int val, Object obj)

теперь вся функция является "атомарной", термин, который я не видел в Java.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы