ProgramaciónDesarrollador Backend

¿Qué es una variable 'volatile' en Java y cómo se diferencia de 'synchronized'? ¿Cuándo y para qué usar volatile?

Supere entrevistas con el asistente de IA Hintsage

Respuesta

volatile es un modificador de variable que garantiza la visibilidad de los cambios de esta variable a todos los hilos. Si una variable se declara como volatile, su lectura y escritura se realizan directamente desde la memoria principal, evitando las cachés locales de los hilos. Esto previene el almacenamiento en caché de valores localmente en el hilo.

synchronized es una palabra clave que proporciona no solo visibilidad, sino también exclusión mutua: solo un hilo puede ejecutar un bloque sincronizado en un momento dado para un objeto.

Se deben usar variables volatile para banderas simples y contadores, si:

  • el valor de la variable no depende del estado anterior (por ejemplo, el contador solo se escribe una vez y se lee muchas veces);
  • no se requiere una secuencia de operaciones más compleja (check-then-act).

Ejemplo de uso de volatile:

class Flag { private volatile boolean running = true; public void stop() { running = false; } public void loop() { while (running) { // ... } } }

Pregunta capciosa

¿Se puede usar volatile para garantizar la atomicidad de la operación de incremento de una variable?

Respuesta: No, volatile no garantiza la atomicidad de las operaciones. Por ejemplo, counter++ no es atómico incluso si counter se declara como volatile, porque la operación involucra lectura, modificación y escritura (varias acciones) que pueden ser interrumpidas por otro hilo. La atomicidad se garantiza mediante synchronized o clases del paquete java.util.concurrent.atomic.

Ejemplo:

class Counter { private volatile int count = 0; public void increment() { count++; // ¡NO es una operación atómica! } }

Ejemplos de errores reales debido a la falta de conocimiento de los matices del tema


Historia

En un proyecto de tienda en línea, la bandera de finalización del hilo de procesamiento de pedidos se implementó sin volatile. Como resultado, uno de los hilos "se atasco" en un ciclo infinito, ya que no veía el cambio de variable realizado desde otro hilo. El diagnóstico tomó varios días.


Historia

En un sistema financiero, un desarrollador utilizó volatile int para un contador de operaciones. En cargas pico, el número de operaciones comenzaba a "perderse". La razón: pérdida de atomicidad en operaciones complejas de incremento.


Historia

Los desarrolladores confundieron volatile y synchronized al intentar usar volatile para garantizar la exclusión mutua del acceso a secciones críticas, lo que llevó a data race y errores difíciles de detectar en una aplicación multihilo.