Booleano volátil vs AtomicBoolean

Resuelto JeffV asked hace 13 años • 12 respuestas

¿Qué hace AtomicBoolean que un booleano volátil no pueda lograr?

JeffV avatar Sep 24 '10 19:09 JeffV
Aceptado

Utilizo campos volátiles cuando dicho campo SÓLO es ACTUALIZADO por su subproceso propietario y el valor solo lo leen otros subprocesos. Puede considerarlo como un escenario de publicación/suscripción donde hay muchos observadores pero solo un editor. Sin embargo, si esos observadores deben realizar alguna lógica basada en el valor del campo y luego retroceder un nuevo valor, entonces uso vars Atomic* o bloqueos o bloques sincronizados, lo que más me convenga. En muchos escenarios concurrentes, todo se reduce a obtener el valor, compararlo con otro y actualizarlo si es necesario, de ahí los métodos compareAndSet y getAndSet presentes en las clases Atomic*.

Consulte los JavaDocs del paquete java.util.concurrent.atomic para obtener una lista de clases Atomic y una excelente explicación de cómo funcionan (acabo de enterarme de que no tienen bloqueos, por lo que tienen una ventaja sobre los bloqueos o bloques sincronizados)

teto avatar Sep 24 '2010 13:09 teto

Son simplemente totalmente diferentes. Considere este ejemplo de un volatilenúmero entero:

volatile int i = 0;
void incIBy5() {
    i += 5;
}

Si dos subprocesos llaman a la función al mismo tiempo, ipodrían ser 5 después, ya que el código compilado será algo similar a este (excepto que no se puede sincronizar int):

void incIBy5() {
    int temp;
    synchronized(i) { temp = i }
    synchronized(i) { i = temp + 5 }
}

Si una variable es volátil, cada acceso atómico a ella se sincroniza, pero no siempre es obvio qué se considera realmente un acceso atómico. Con un Atomic*objeto, se garantiza que cada método sea "atómico".

Por lo tanto, si usa un AtomicIntegery getAndAdd(int delta), puede estar seguro de que el resultado será 10. De la misma manera, si dos subprocesos niegan una booleanvariable al mismo tiempo, con an AtomicBooleanpuede estar seguro de que tiene el valor original después, con a volatile booleanno puede hacerlo.

Entonces, siempre que tenga más de un hilo modificando un campo, debe hacerlo atómico o usar sincronización explícita.

El propósito de volatilees otro. Considere este ejemplo

volatile boolean stop = false;
void loop() {
    while (!stop) { ... }
}
void stop() { stop = true; }

Si tiene un subproceso ejecutándose loop()y otro subproceso llamando a stop(), podría encontrarse con un bucle infinito si omite volatile, ya que el primer subproceso podría almacenar en caché el valor de parada. Aquí, esto volatilesirve como una pista para que el compilador sea un poco más cuidadoso con las optimizaciones.

Cephalopod avatar Sep 24 '2010 12:09 Cephalopod

compareAndSetNo puede hacerlo getAndSetcomo operación atómica con booleano volátil (a menos, por supuesto, que lo sincronice).

nanda avatar Sep 24 '2010 12:09 nanda