En la programación multiproceso de Java, a menudo se encuentra volátil. A veces, esta palabra clave a menudo se confunde con sincronizado o bloqueo. El análisis específico es el siguiente:
En un entorno múltiple, habrá un problema de visibilidad de las variables miembros: cada hilo en Java tiene un espacio de memoria de una pila de subprocesos, que guarda la información variable del hilo cuando se está ejecutando. Cuando un subproceso accede a un cierto valor variable, primero encontrará la memoria del montón del objeto o el contenido específico de la pila (tipo de datos nativo) en función de la dirección de la variable, y luego guardará la misma copia de valor en la pila de subprocesos de este hilo. Luego, todas las operaciones en esta variable no tienen nada que ver con el contenido variable en la pila antes de que salga el subproceso. Funciona en la copia en la pila de subprocesos. Después de completar la operación, el resultado de la operación se volverá a escribir a la memoria principal. Si hay dos hilos A y B, y los colegas operan una cierta variable x; A agrega 1 a x, entonces la copia obtenida por B puede ser el resultado de x más 1 o x; Para garantizar que se necesite la última variable de datos en la memoria para agregar la palabra clave volátil, por lo que cada vez que opera en X, verificará si el valor de la variable en la pila de subprocesos es el mismo que el valor de la variable en la memoria, y si es diferente, se cargará nuevamente.
p.ej:
Public Class ThreadSee {// El hilo T1 realizará las operaciones correspondientes en función del valor de la bandera, y el hilo principal cambiará el valor de T1 public static void main (string [] args) lanza interruptedException {threadtest th = new ThreadTest (); Hilo t1 = nuevo hilo (th); t1.start (); Thread.sleep (1000); th.changeFlag (); Thread.sleep (2000); System.out.println (th.getFlag ()); }} La clase ThreadTest implementa Runnable {// Cuando un subproceso accede a una variable, la cargará en la pila de subprocesos correspondiente. Cada operación, debe obtener los últimos datos en memoria de la memoria Private Volatile Boolean StopFlag; @Override public void run () {int i = 0; while (! stopflag) {i ++; System.out.println ("=="+thread.currentThread (). GetName ()); } System.out.println ("Final de hilo:"+i); } public void ChangeFlag () {this.stopflag = true; System.out.println (thread.currentThread (). GetName ()+"*********"); } public boolean getFlag () {return stopflag; }} Si se elimina el código anterior, continuará ejecutándose en un bucle muerto.
Pero volátil no puede garantizar la sincronización segura de hilo
p.ej:
Public Class ThreadSave implementa Runnable {static Threadsave sync = new Threadsave (); Volátil estático int j = 0; // bloqueo de bloqueo = nuevo reentrantlock (); public void Inscane () {// Lock.lock (); para (int i = 0; i <10000000; i ++) {j ++; } // Lock.unlock (); } @Override public void run () {inscane (); } public static void main (string [] args) lanza interruptedException {hilo t1 = nuevo hilo (sincronización); Hilo t2 = nuevo hilo (sincronización); t1.start (); t2.start (); t1.Join (); t2.join (); System.out.println (j); }} No se espera que el resultado de la ejecución de acuerdo con el código anterior sea 20000000,
Porque para las variables modificadas por Volatile, la máquina virtual JVM solo asegura que el valor cargado de la memoria principal a la memoria de trabajo de subprocesos sea el último.
Por ejemplo, si Thread 1 y Thread 2 están realizando operaciones de lectura y carga de la memoria principal y la memoria principal, y encuentre que el valor del recuento en la memoria principal es 5, entonces se cargará el último valor. Después de modificar el recuento de montón de subproceso 1, se escribirá en la memoria principal, y la variable de recuento en la memoria principal se convertirá en 6;
Dado que Thread 2 ya ha realizado operaciones de lectura y carga, después de realizar la operación, el valor variable del recuento de memoria principal también se actualizará a 6;
Esto hace que ocurra la concurrencia después de que dos hilos se modifican con la palabra clave volátil en el tiempo.
En resumen:
Volátil solo se asegurará de que el hilo realice una acción que verifique si el valor variable de la pila de subproceso actual es el mismo que el valor de datos en la memoria principal, eso es todo. Bloqueo o sincronizado asegurará que solo un solo hilo ingrese al método en un momento determinado, asegurando así la seguridad de su hilo.
Entonces, si múltiples hilos modifican una variable volátil, entonces no hay un significado lógico real. Si un hilo modifica el valor variable de otros hilos que dependen de modificar, será útil en este momento.
Lo anterior se trata de este artículo, espero que sea útil para el aprendizaje de todos.