Какие операции в 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.