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

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

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();

?


person Rox    schedule 10.11.2011    source источник


Ответы (4)


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

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

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

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

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

  • синхронизированные блоки
  • неизменяемые объекты
  • определенные библиотеки (java.util.concurrent.atomic)
person PeterMmm    schedule 10.11.2011
comment
Спасибо за Ваш ответ! Я также отредактировал свой вопрос, поэтому теперь он включает пример кода при использовании ссылки на объект в вызове метода. - person Rox; 10.11.2011

Когда поток читает значение примитива (кроме 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 не является атомарным.

person JB Nizet    schedule 10.11.2011
comment
Спасибо, что упомянули отношения «Происходит раньше». - person dmeister; 10.11.2011

За JLS!

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

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

person Tim Bender    schedule 10.11.2011

public synchronized void setValue(int val, Object obj)

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

person Nicholas Jordan    schedule 10.11.2011