¿Para qué sirve la palabra clave volátil?

Resuelto Richard asked hace 16 años • 25 respuestas

Hoy en el trabajo, encontré la volatilepalabra clave en Java. Al no estar muy familiarizado con ello, encontré esta explicación .

Dado el detalle en el que ese artículo explica la palabra clave en cuestión, ¿la usa alguna vez o podría ver algún caso en el que pueda usar esta palabra clave de la manera correcta?

Richard avatar Sep 20 '08 07:09 Richard
Aceptado

volatiletiene semántica para la visibilidad de la memoria. Básicamente, el valor de un volatilecampo se vuelve visible para todos los lectores (otros hilos en particular) después de que se completa una operación de escritura en él. Sin volatile, los lectores podrían ver algún valor no actualizado.

Para responder a su pregunta: Sí, uso una volatilevariable para controlar si algún código continúa un bucle. El bucle prueba el volatilevalor y continúa si es true. La condición se puede establecer falsellamando a un método de "detención". El bucle detecta falsey finaliza cuando prueba el valor después de que el método de detención completa la ejecución.

El libro " Java Concurrency in Practice ", que recomiendo encarecidamente, ofrece una buena explicación volatile. Este libro está escrito por la misma persona que escribió el artículo de IBM al que se hace referencia en la pregunta (de hecho, cita su libro al final de ese artículo). Mi uso volatilees lo que su artículo llama "indicador de estado del patrón 1".

Si desea obtener más información sobre cómo volatilefunciona internamente, lea sobre el modelo de memoria Java . Si desea ir más allá de ese nivel, consulte un buen libro sobre arquitectura informática como Hennessy & Patterson y lea sobre coherencia de caché y consistencia de caché.

Greg Mattes avatar Sep 20 '2008 02:09 Greg Mattes

"... el modificador volátil garantiza que cualquier hilo que lea un campo verá el valor escrito más recientemente". - Josh Bloch

Si está pensando en utilizar volatile, lea el paquete java.util.concurrentque trata sobre el comportamiento atómico.

La publicación de Wikipedia sobre un patrón Singleton muestra un uso volátil.

Ande Turner avatar Sep 20 '2008 00:09 Ande Turner

Volátil (vɒlətʌɪl): Se evapora fácilmente a temperaturas normales.

Punto importante sobre volatile:

  1. La sincronización en Java es posible mediante el uso de palabras clave de Java synchronizedy volatilebloqueos.
  2. En Java, no podemos tener synchronizedvariables. El uso synchronizedde palabras clave con una variable es ilegal y provocará un error de compilación. En lugar de usar la synchronizedvariable en Java, puede usar la volatilevariable java, que indicará a los subprocesos JVM que lean el valor de la volatilevariable de la memoria principal y no lo almacenen en caché localmente.
  3. Si una variable no se comparte entre varios subprocesos, no es necesario utilizar la volatilepalabra clave.

fuente

Ejemplo de uso de volatile:

public class Singleton {
    private static volatile Singleton _instance; // volatile variable
    public static Singleton getInstance() {
        if (_instance == null) {
            synchronized (Singleton.class) {
                if (_instance == null)
                    _instance = new Singleton();
            }
        }
        return _instance;
    }
}

Estamos creando una instancia de forma perezosa en el momento en que llega la primera solicitud.

Si no creamos la _instancevariable volatile, entonces el subproceso que está creando la instancia Singletonno podrá comunicarse con el otro subproceso. Entonces, si el subproceso A está creando una instancia Singleton y justo después de la creación, la CPU se corrompe, etc., todos los demás subprocesos no podrán ver el valor de _instancecomo no nulo y creerán que todavía está asignado como nulo.

¿Por qué pasó esto? Debido a que los subprocesos del lector no realizan ningún bloqueo y hasta que el subproceso del escritor salga de un bloque sincronizado, la memoria no se sincronizará y el valor de _instanceno se actualizará en la memoria principal. Con la palabra clave Volatile en Java, esto lo maneja el propio Java y dichas actualizaciones serán visibles para todos los hilos de lectores.

Conclusión : volatilela palabra clave también se utiliza para comunicar el contenido de la memoria entre subprocesos.

Ejemplo de uso de sin volátil:

public class Singleton {    
    private static Singleton _instance;   //without volatile variable
    public static Singleton getInstance() {   
        if (_instance == null) {  
            synchronized(Singleton.class) {  
                if (_instance == null) 
                    _instance = new Singleton(); 
            } 
        }
        return _instance;  
    }
}

El código anterior no es seguro para subprocesos. Aunque verifica el valor de la instancia una vez más dentro del bloque sincronizado (por razones de rendimiento), el compilador JIT puede reorganizar el código de bytes de manera que la referencia a la instancia se establezca antes de que el constructor haya terminado su ejecución. Esto significa que el método getInstance() devuelve un objeto que quizás no se haya inicializado por completo. Para que el código sea seguro para subprocesos, la palabra clave volátil se puede utilizar desde Java 5 para la variable de instancia. Las variables marcadas como volátiles solo son visibles para otros subprocesos una vez que el constructor del objeto ha finalizado su ejecución por completo.
Fuente

ingrese la descripción de la imagen aquí

volatileuso en Java :

Los iteradores a prueba de fallas generalmente se implementan utilizando un volatilecontador en el objeto de lista.

  • Cuando se actualiza la lista, se incrementa el contador.
  • Cuando se crea un Iterator, el valor actual del contador se incrusta en el Iteratorobjeto.
  • Cuando Iteratorse realiza una operación, el método compara los dos valores del contador y arroja un ConcurrentModificationExceptionsi son diferentes.

La implementación de iteradores a prueba de fallos suele ser ligera. Por lo general, se basan en propiedades de las estructuras de datos de la implementación de la lista específica. No existe un patrón general.

Premraj avatar Dec 18 '2015 21:12 Premraj

volatileEs muy útil para detener hilos.

No es que debas escribir tus propios hilos, Java 1.6 tiene muchos grupos de hilos interesantes. Pero si está seguro de que necesita un hilo, necesitará saber cómo detenerlo.

El patrón que uso para los hilos es:

public class Foo extends Thread {

  private volatile boolean close = false;

  public void run() {
    while(!close) {
      // do work
    }
  }
  public void close() {
    close = true;
    // interrupt here if needed
  }
}

En el segmento de código anterior, el hilo que lee closeen el bucle while es diferente del que llama close(). Sin volátil, es posible que el hilo que ejecuta el bucle nunca vea el cambio para cerrarse.

Observe cómo no hay necesidad de sincronización

Pyrolistical avatar Sep 24 '2008 22:09 Pyrolistical

Una variable declarada con volatilepalabra clave tiene dos cualidades principales que la hacen especial.

  1. Si tenemos una variable volátil, ningún hilo puede almacenarla en caché en la memoria caché de la computadora (microprocesador). El acceso siempre se produjo desde la memoria principal.

  2. Si hay una operación de escritura en una variable volátil y de repente se solicita una operación de lectura , se garantiza que la operación de escritura finalizará antes de la operación de lectura .

De las dos cualidades anteriores se deduce que

  • Todos los hilos que lean una variable volátil definitivamente leerán el último valor. Porque ningún valor almacenado en caché puede contaminarlo. Y además, la solicitud de lectura se concederá sólo después de completar la operación de escritura actual.

Y por otro lado,

  • Si investigamos más a fondo el punto 2 que he mencionado, podemos ver que volatilela palabra clave es una forma ideal de mantener una variable compartida que tiene 'n' número de subprocesos de lectura y solo un subproceso de escritura para acceder a ella. Una vez que agregamos la volatilepalabra clave, listo. No hay ningún otro comentario general sobre la seguridad de los subprocesos.

Por el contrario,

No podemos utilizar volatilepalabras clave únicamente para satisfacer una variable compartida a la que más de un hilo de escritura accede a ella .

Supun Wijerathne avatar Mar 04 '2018 18:03 Supun Wijerathne