Что такое атомное? - PullRequest
       27

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

3 голосов
/ 10 ноября 2011

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

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

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

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

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

Object obj = null;

и

Object obj = new Object();

Ответы [ 4 ]

4 голосов
/ 10 ноября 2011

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

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

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

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

Если вам нужноДля обеспечения атомарных операций у вас есть различные возможности:

  • синхронизированные блоки
  • неизменяемые объекты
  • специальные библиотеки (java.util.concurrent.atomic)
3 голосов
/ 10 ноября 2011

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

Однако, хотя присвоение значения общей переменной в одном потоке является атомарным, это не означает, что все остальные потоки увидят новое значение сразу после.Для этого переменная должна быть объявлена ​​как volatile.volatile также делает записи в длинные и двойные атомные.Однако в этом случае я предпочитаю использовать 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 не является атомарным.

1 голос
/ 10 ноября 2011

К JLS!

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

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

0 голосов
/ 10 ноября 2011
public synchronized void setValue(int val, Object obj)

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

...