¿Qué significa "atómico" en la programación?

276

En el libro de Effective Java, dice:

La especificación del lenguaje garantiza que leer o escribir una variable es atómica a menos que la variable sea de tipo longo double[JLS, 17.4.7].

¿Qué significa "atómico" en el contexto de la programación Java, o la programación en general?

James
fuente
24
Una operación a la vez.
Subhrajyoti Majumder
1
solo se puede realizar una operación en la variable a la vez.
kaysush
1
Sospecho que las preguntas de filosofía pertenecen a codereview.stackexchange.com
Phlip
Observando que algunas variables no tienen por defecto lectura y escritura atómica, declarándolas como volatile longo volatile doublehace que la lectura atómica y la escritura atómica.
H2ONaCl

Respuestas:

372

Aquí hay un ejemplo, porque un ejemplo a menudo es más claro que una explicación larga. Supongamos que fooes una variable de tipo long. La siguiente operación no es una operación atómica:

foo = 65465498L;

De hecho, la variable se escribe utilizando dos operaciones separadas: una que escribe los primeros 32 bits y otra que escribe los últimos 32 bits. Eso significa que otro hilo podría leer el valor de fooy ver el estado intermedio.

Hacer que la operación sea atómica consiste en utilizar mecanismos de sincronización para asegurarse de que la operación se vea, desde cualquier otro hilo, como una operación única, atómica (es decir, no dividible en partes). Eso significa que cualquier otro subproceso, una vez que la operación se vuelva atómica, verá el valor fooantes o después de la asignación. Pero nunca el valor intermedio.

Una manera simple de hacer esto es hacer que la variable sea volátil :

private volatile long foo;

O para sincronizar cada acceso a la variable:

public synchronized void setFoo(long value) {
    this.foo = value;
}

public synchronized long getFoo() {
    return this.foo;
}
// no other use of foo outside of these two methods, unless also synchronized

O para reemplazarlo con un AtomicLong:

private AtomicLong foo;
JB Nizet
fuente
75
Entonces, se supone que se está ejecutando en un sistema de 32 bits. ¿Qué pasa si se trata de un sistema de 64 bits? Will foo = 65465498L; ser atómico entonces?
Harke
46
@ Harke Si está ejecutando Java de 64 bits, sí.
Jeroen
44
¿Esto también se aplica a C # y .NET? En caso afirmativo, para obtener un comportamiento atómico, ¿el CLR debe ser de 64 bits?
Fabiano
55
@Fabiano Se aplica y así es cómo lograrlo en .NET ya que no tenemos la palabra clave sincronizada como Java. stackoverflow.com/questions/541194/…
The Muffin Man
2
Entonces supongamos que el hilo A asigna un valor largo y luego, a la mitad, el hilo B intenta leerlo. Si la operación A es atómica, ¿el hilo B esperará hasta que termine? Esto significa que las operaciones atómicas proporcionarán seguridad implícita de subprocesos?
Teoman shipahi
60

"Operación atómica" significa una operación que parece ser instantánea desde la perspectiva de todos los otros hilos. No necesita preocuparse por una operación parcialmente completa cuando se aplica la garantía.

H2ONaCl
fuente
25

Es algo que "parece que el resto del sistema ocurre instantáneamente" y se clasifica en la categorización de linealización en los procesos informáticos. Para citar aún más ese artículo vinculado:

La atomicidad es una garantía de aislamiento de los procesos concurrentes. Además, las operaciones atómicas suelen tener una definición de éxito o fracaso: cambian con éxito el estado del sistema o no tienen ningún efecto aparente.

Entonces, por ejemplo, en el contexto de un sistema de base de datos, uno puede tener 'compromisos atómicos', lo que significa que puede enviar un conjunto de cambios de actualizaciones a una base de datos relacional y esos cambios se enviarán todos o ninguno de ellos en absoluto En caso de falla, de esta manera los datos no se corrompen, y como consecuencia de bloqueos y / o colas, la siguiente operación será una escritura o lectura diferente, pero solo después del hecho. En el contexto de variables y subprocesos, esto es muy similar, aplicado a la memoria.

Su cita destaca que este comportamiento no tiene que ser esperado en todos los casos.

Grant Thomas
fuente
15

Acabo de encontrar una publicación de Operaciones atómicas frente a operaciones no atómicas que me fue muy útil.

"Una operación que actúa en la memoria compartida es atómica si se completa en un solo paso en relación con otros subprocesos.

Cuando se realiza un almacenamiento atómico en una memoria compartida, ningún otro subproceso puede observar la modificación a medio completar.

Cuando se realiza una carga atómica en una variable compartida, lee el valor completo tal como apareció en un solo momento en el tiempo ".

Kurt Zhong
fuente
14

Si tiene varios subprocesos ejecutando los métodos m1 y m2 en el siguiente código:

class SomeClass {
    private int i = 0;

    public void m1() { i = 5; }
    public int m2() { return i; }
}

tiene la garantía de que cualquier llamada de hilo m2leerá 0 o 5.

Por otro lado, con este código (donde ies largo):

class SomeClass {
    private long i = 0;

    public void m1() { i = 1234567890L; }
    public long m2() { return i; }
}

una llamada de subproceso m2podría leer 0, 1234567890L o algún otro valor aleatorio porque i = 1234567890Lno se garantiza que la declaración sea ​​atómica para a long(una JVM podría escribir los primeros 32 bits y los últimos 32 bits en dos operaciones y un subproceso podría observar ien el medio) .

asilias
fuente
¿Por qué crees que "largo" causa problemas mientras que "int" no? Consulte aquí geekswithblogs.net/BlackRabbitCoder/archive/2012/08/09/…
onmyway133
1
No se garantiza que las asignaciones largas y dobles de @entropy sean atómicas en Java. Por lo tanto, podría leer un largo donde solo la mitad de los bits se han actualizado después de una asignación.
Assylias
0

En Java, la lectura y escritura de campos de todo tipo, excepto long y double, se produce atómicamente, y si el campo se declara con el modificador volátil, incluso long y double se leen y escriben atómicamente. Es decir, obtenemos el 100% de lo que estaba allí o de lo que sucedió allí, ni puede haber ningún resultado intermedio en las variables.

Eugene Shamkin
fuente