Sabemos que las operaciones para establecer valores de variables en Java son operaciones atómicas, excepto las variables de tipo largo y doble. En otras palabras, no es necesario sincronizar operaciones simples de lectura y escritura de valores de variables.
Antes de JVM 1.2, la implementación del modelo de memoria de Java siempre leía variables de la memoria principal, lo que no requería atención especial. Con la madurez y optimización de JVM, el uso de palabras clave volátiles se ha vuelto muy importante en entornos multiproceso. Según el modelo de memoria Java actual, los subprocesos pueden almacenar variables en la memoria local (como registros de máquina) en lugar de leer y escribir directamente en la memoria principal. Esto puede hacer que un subproceso modifique el valor de una variable en la memoria principal, mientras que otro subproceso continúa usando su copia del valor de la variable en el registro, lo que provoca inconsistencia en los datos. Para resolver este problema, solo necesita declarar la variable como volátil (inestable) como en este programa. Esto le indica a la JVM que esta variable es inestable y se almacenará en la memoria principal cada vez que se use para leer. En términos generales
Por lo tanto, en un entorno multitarea, los indicadores compartidos entre tareas deben modificarse con volátiles.
Cada vez que un hilo accede a una variable miembro modificada por Volatile, se fuerza a releer el valor de la variable miembro desde la memoria compartida. Además, cuando una variable miembro cambia, el hilo se ve obligado a escribir el valor modificado nuevamente en la memoria compartida. De esta forma, en cualquier momento, dos hilos diferentes siempre ven el mismo valor de una variable miembro.
La especificación del lenguaje Java establece: Para una velocidad óptima, los subprocesos pueden guardar copias privadas de variables miembro compartidas y compararlas con los valores originales de las variables miembro compartidas solo cuando el subproceso ingresa o sale de un bloque de código sincronizado.
De esta manera, cuando varios subprocesos interactúan con un objeto al mismo tiempo, se debe prestar atención a permitir que los subprocesos obtengan cambios en las variables miembro compartidas de manera oportuna.
La palabra clave volátil le indica a la VM: no puede guardar una copia privada de esta variable miembro, pero debe interactuar directamente con la variable miembro compartida.
Sugerencia de uso: use volátil en variables miembro a las que acceden dos o más subprocesos. No es necesario utilizarlo cuando la variable a acceder ya se encuentra en un bloque de código sincronizado o es una constante.
Dado que el uso de volátil bloquea la optimización del código necesaria en la VM, es menos eficiente, por lo que esta palabra clave debe usarse solo cuando sea necesario.
En la implementación de la máquina virtual, los tipos básicos como int y char tienen una longitud de una palabra. Y long y double ocupan dos palabras de longitud. En algunas implementaciones de máquinas virtuales, las dos longitudes de palabras pueden tratarse como dos longitudes atómicas de una sola palabra.
Si long y double no se modifican con volátil, si varios subprocesos acceden a la variable, el resultado será confuso debido a la no atomicidad general de la operación larga.
Por ejemplo: int, un hilo escribe 4 y otro escribe 5. El valor final debe ser 4 o 5. Y el tipo largo puede ser un valor desordenado.