¿Qué operaciones en Java se consideran atómicas?

Respuestas:

100
  • todas las asignaciones de tipos primitivos excepto long y double
  • todas las asignaciones de referencias
  • todas las asignaciones de variables volátiles
  • todas las operaciones de las clases java.concurrent.Atomic *

y quizás algo más. Mira el jls .

Como se señaló en los comentarios, la atomicidad no implica visibilidad. Entonces, aunque se garantiza que otro hilo no verá un escrito parcialmente int, es posible que nunca vea el nuevo valor.

Las operaciones en long y double también se realizan en CPU atómicas comunes de 64 bits , aunque no hay garantía. Consulte también esta solicitud de función .

maaartinus
fuente
21
volatileSe garantiza que las asignaciones a largos y dobles serán atómicas: java.sun.com/docs/books/jls/third_edition/html/memory.html#17.7
Joonas Pulakka
12
Además, tenga en cuenta que mientras que las operaciones son atómicas, la visibilidad de las operaciones podría no ser garantizado en una aplicación multiproceso si no se toman cuidados especiales (los detalles aquí son manera a intrincados para describir en un comentario ..)
nn
5
64 bit jvm, long and double assignments are also atomic.¿Estás seguro? Yo diría que son para código compilado, pero ¿qué pasa con el código interpretado? Probablemente tengas razón, pero ¿hay alguna garantía?
maaartinus
4
La especificación aún no exige que las JVM de 64 bits proporcionen atomicidad a las asignaciones largas y dobles. java.sun.com/docs/books/jls/third_edition/html/memory.html#17.7 En sus famosas palabras, "este comportamiento es específico de la implementación". Sin embargo, lo más probable es que las máquinas virtuales de 64 bits lo implementen como una operación atómica.
sjlee
1
En mi humilde opinión, las asignaciones de referencia normales son atómicas, pero AtomicReference ofrece más: compareAndSet y getAndSet, que es algo que no podría lograr de otra manera sin sincronización.
maaartinus
5

En Java, se garantiza que la lectura y escritura de cantidades de 32 bits o menores son atómicas.
Por atómico, queremos decir que cada acción tiene lugar en un paso y no puede interrumpirse. Por lo tanto, cuando tenemos aplicaciones multiproceso, las operaciones de lectura y escritura son seguras para los subprocesos y no es necesario sincronizarlas.

Por ejemplo, el siguiente código es seguro para subprocesos:

public class ThreadSafe   
  {  
    private int x;  
    public void setX(int x)  
          {
           this.x = x;
           } 
  }
sgokhales
fuente
5
..threadsafe en el sentido de que el valor siempre será exactamente el valor original o el valor establecido. El valor más actualizado todavía no es necesariamente visible para otros hilos debido a la falta de "volátil" o "sincronizado".
Mikko Wilkman
1
+1 a lo que dice @MikkoWilkman. Ese fragmento de código no debe usarse ya que definitivamente no es seguro para subprocesos desde una perspectiva de visibilidad de memoria.
Knuckles the Echidna
0

Sería parece que las asignaciones de posiciones largas son atómicas, sobre la base de este método en AtomicLong.java:

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

Tenga en cuenta la ausencia de sincronización.

Lyle Z
fuente
3
Mira la declaración de value. Es volatile.
maaartinus
2
Eso valuees volatileno realizar la asignación de value, simplemente evita la "publicación" cuestiones atómicas.
Lyle Z
7
Hace ambas cosas, consulte JLS, sección 17.7 : Las escrituras y lecturas de valores volátiles largos y dobles siempre son atómicas.
maaartinus
@LyleZ el comentario más valioso de este hilo, en mi opinión.
stdout