Aquí hay un ejemplo, porque un ejemplo a menudo es más claro que una explicación larga. Supongamos que foo
es 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 foo
y 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 foo
antes 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;