threads thread practice example java concurrency

thread - ¿Cuándo necesito usar AtomicBoolean en Java?



thread java (5)

¿Cómo puedo usar AtomicBoolean y para qué sirve esa clase?


Aquí están las notas (del libro de Brian Goetz) que hice que podrían ser de ayuda para ti

Clases de AtomicXXX

  • proporcionar implementación sin bloqueo Compare-And-Swap

  • Aprovecha el soporte brindado por el hardware (la instrucción CMPXCHG en Intel) Cuando muchos subprocesos se ejecutan a través de su código que usa estas API de concurrencia atómica, escalarán mucho mejor que el código que usa monitores / sincronización de nivel de objeto. Dado que los mecanismos de sincronización de Java hacen que el código espere, cuando hay muchos subprocesos que se ejecutan a través de sus secciones críticas, se gasta una cantidad considerable de tiempo de CPU en la administración del mecanismo de sincronización (esperar, notificar, etc.). Dado que la nueva API utiliza construcciones de nivel de hardware (variables atómicas) y algoritmos de espera y bloqueo para implementar seguridad de subprocesos, se gasta mucho más tiempo de CPU "haciendo cosas" en lugar de administrar la sincronización.

  • no solo ofrecen un mejor rendimiento, sino que también proporcionan una mayor resistencia a los problemas de vida, como el punto muerto y la inversión de prioridad.


Cuando varios hilos necesitan verificar y cambiar el booleano. Por ejemplo:

if (!initialized) { initialize(); initialized = true; }

Esto no es seguro para subprocesos. Puedes arreglarlo usando AtomicBoolean :

if (atomicInitialized.compareAndSet(false, true)) { initialize(); }


Extracto de la descripción del paquete

Descripción del paquete java.util.concurrent.atomic: Un pequeño conjunto de herramientas de clases que admiten la programación sin bloqueo seguro de subprocesos en variables individuales. [...]

Las especificaciones de estos métodos permiten a las implementaciones emplear instrucciones atómicas eficaces a nivel de máquina que están disponibles en procesadores contemporáneos. [...]

Las instancias de las clases AtomicBoolean, AtomicInteger, AtomicLong y AtomicReference proporcionan acceso y actualizaciones a una única variable del tipo correspondiente. [...]

Los efectos de memoria para los accesos y las actualizaciones de atomics generalmente siguen las reglas para volátiles:

  • get tiene los efectos de memoria de leer una variable volátil.
  • set tiene los efectos de memoria de escribir (asignar) una variable volátil.
  • weakCompareAndSet lee atómicamente y escribe condicionalmente una variable, se ordena con respecto a otras operaciones de memoria en esa variable, pero de lo contrario actúa como una operación ordinaria de memoria no volátil.
  • compareAndSet y todas las demás operaciones de lectura y actualización, como getAndIncrement, tienen los efectos de memoria de lectura y escritura de variables volátiles.

Hay dos razones principales por las que puedes usar un booleano atómico. Primero es mutable, puede pasarlo como referencia y cambiar el valor que está asociado al booleano, por ejemplo.

public final class MyThreadSafeClass{ private AtomicBoolean myBoolean = new AtomicBoolean(false); private SomeThreadSafeObject someObject = new SomeThreadSafeObject(); public boolean doSomething(){ someObject.doSomeWork(myBoolean); return myBoolean.get(); //will return true } }

y en la clase someObject

public final class SomeThreadSafeObject{ public void doSomeWork(AtomicBoolean b){ b.set(true); } }

Sin embargo, lo más importante es que su hilo es seguro y puede indicar a los desarrolladores que mantienen la clase, que se espera que esta variable se modifique y se lea desde múltiples hilos. Si no utiliza un AtomicBoolean, debe sincronizar la variable booleana que está utilizando al declararla volátil o sincronizarla alrededor de la lectura y escritura del campo.