Какие операции в Java считаются атомарными?

Ответы:

100
  • все присваивания примитивных типов, кроме long и double
  • все назначения ссылок
  • все присвоения изменчивых переменных
  • все операции классов java.concurrent.Atomic *

а может что-то еще. Посмотрите на jls .

Как отмечено в комментариях, атомарность не подразумевает видимости. Таким образом, хотя другой поток гарантированно не увидит частично написанное int, он может никогда не увидеть новое значение.

Операции с long и double также выполняются на обычных 64-битных процессорах atomic , хотя нет никаких гарантий. См. Также этот запрос функции .

мааартинус
источник
21
Назначения на volatileдлинные и двойные позиции гарантированно будут атомарными: java.sun.com/docs/books/jls/third_edition/html/memory.html#17.7
Joonas Pulakka
12
Кроме того , имейте в виду , что в то время как операции являются атомарными, видимость этих операций может не быть гарантировано в многопоточном приложении , если специальный уход не берется (подробности здесь способ замысловатых описать в комментарии ..)
NOS
5
64 bit jvm, long and double assignments are also atomic.Вы уверены? Я бы сказал, что они предназначены для скомпилированного кода, но как насчет интерпретируемого кода? Наверное, ты прав, но есть ли гарантия?
maaartinus
4
Спецификация по-прежнему не требует, чтобы 64-битные JVM обеспечивали атомарность для длинных и двойных назначений. java.sun.com/docs/books/jls/third_edition/html/memory.html#17.7 По его знаменитым словам, «это поведение зависит от реализации». Однако, скорее всего, 64-битные виртуальные машины будут реализовывать это как атомарную операцию.
sjlee
1
ИМХО, обычные ссылочные присвоения являются атомарными, но AtomicReference предлагает больше: compareAndSet и getAndSet, чего вы не смогли бы достичь без синхронизации.
maaartinus
5

В Java чтение и запись 32-битных или меньших количеств гарантированно атомарны.
Под атомарным мы подразумеваем, что каждое действие происходит за один шаг и не может быть прервано. Таким образом, когда у нас есть многопоточные приложения, операции чтения и записи являются потокобезопасными и не требуют синхронизации.

Например, следующий код является потокобезопасным:

public class ThreadSafe   
  {  
    private int x;  
    public void setX(int x)  
          {
           this.x = x;
           } 
  }
сгохалес
источник
5
..threadsafe в том смысле, что значение всегда будет либо исходным, либо установленным значением. Самое актуальное значение по-прежнему обязательно не отображается для других потоков из-за отсутствия «изменчивого» или «синхронизированного».
Микко Вилкман
1
+1 к тому, что говорит @MikkoWilkman. Этот фрагмент кода не следует использовать, поскольку он определенно небезопасен с точки зрения видимости памяти.
Knuckles the Echidna
0

Было бы показаться , что уступка долгот атомарные, на основе этого метода в AtomicLong.java:

public final void set(long newValue) {
    value = newValue;
}

Обратите внимание на отсутствие какой-либо синхронизации.

Лайл З
источник
3
Посмотрите декларацию value. Это volatile.
maaartinus
2
То valueесть volatileне делает назначение valueатомных, он просто избегает «публикации» вопросов.
Lyle Z
7
Он делает и то, и другое, см. JLS, раздел 17.7 : Запись и чтение изменчивых длинных и двойных значений всегда атомарны.
maaartinus
@LyleZ, на мой взгляд, самый ценный комментарий в этой ветке.
stdout