semántica volátil de Java

volátil se utiliza para garantizar la visibilidad.

  • Durante la ejecución de un hilo, todos los datos se mantienen en su propia memoria local, y la memoria local de cada hilo es independiente entre sí y no se afecta entre sí. Generalmente se escribe en la memoria principal hasta que el hilo ha terminado de ejecutarse. De esta manera, cuando el hilo opera la variable compartida, habrá inconsistencia de datos, volátil es permitir que la variable compartida se actualice a la memoria principal a tiempo.
  • La volátil no es atómica, solo para garantizar que los datos recuperados en el segundo anterior sean los últimos, pero no hay forma de modificar los datos para otros subprocesos en el siguiente segundo. No es útil para operaciones de conteo ++ y operaciones a = b. De

semántica volátil

  • Al escribir una variable volátil, JMM actualizará el valor de la variable compartida en la memoria local correspondiente al hilo a la memoria principal.
  • Al leer una variable volátil, JMM invalidará la memoria local correspondiente al hilo. El hilo leerá la variable compartida de la memoria principal.

Ejemplos:

a, prueba son dos referencias al mismo objeto.
 private static volatile  Test test = new Test("4545",45);
     static Test a = test;
    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            while ("4545".equals(test.getName())){
            }
        }).start();

        Thread.sleep(100);
        a.setName("343434");
En el ejemplo anterior, el objeto de prueba agregó volátil. Por lo tanto, el subproceso test.getName (); siempre puede obtener los datos de la memoria principal, por lo que cuando el subproceso principal cambia, el subproceso puede leerlo para que no se repita sin parar.
 private static volatile  Test test = new Test("4545",45);
     static Test a = test;
    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            while ("4545".equals(a.getName())){
            }
        }).start();

        Thread.sleep(100);
        a.setName("343434");

Esto provocará un bucle sin fin, porque el subproceso secundario se ejecuta primero, por lo que el valor de a en la memoria local del subproceso secundario no cambiará con el subproceso principal. El cambio de a.setName () a test.setName () tampoco funcionará. Antes de que finalice el subproceso secundario, no irá al subproceso principal para leer los datos.

  • Para el caso de un ciclo infinito, podemos dejar que el hilo secundario lea una variable volátil, porque el hilo secundario se ejecuta primero, por lo que debemos escribir una variable volátil de lectura en el ciclo.
  while ("4545".equals(a.getName())){
  			test.getName();
       }

De esta forma, abandonará la memoria local del subproceso secundario y cargará datos desde la memoria principal. Después de 100 ms, el subproceso principal cambia el valor del nombre y el bucle se detiene.

Pasado

  • El valor de a en el subproceso secundario es diferente del valor en el subproceso principal.
 private static volatile  Test test = new Test("4545",45);
    private static volatile  Test test1 = new Test("4545",45);
     static Test a = test;
    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            while ("4545".equals(a.getName())){
                System.out.println("子线程中a的值 "+a.getName());
            }
        }).start();

        Thread.sleep(100);
        a.setName("343434");
        while (true){
            System.out.println("主线程中a的值 "+a.getName());
        }


    }

Resultado de la operación

j resultado

Publicado 21 artículos originales · ganó 24 · vistas 20,000 +

Supongo que te gusta

Origin blog.csdn.net/qq_30332665/article/details/105385290
Recomendado
Clasificación