¿Alguna vez usas la palabra clave volátil en Java?


En el trabajo de hoy, me encontré con la palabra clave volatile en Java. Al no estar muy familiarizado con él, encontré esta explicación:

Teoría y práctica de Java: Gestión de la volatilidad

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

Author: Daniel Werner, 2008-09-20

21 answers

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

Para responder a tu pregunta: Sí, utilizo una variable volatile para controlar si algún código continúa un bucle. El bucle prueba el valor volatile y continúa si es true. La condición se puede establecer en false llamando a un método "stop". El bucle ve false y termina cuando prueba el valor después de que el método stop complete la ejecución.

El libro "Java Concurrency in Practice," que recomiendo encarecidamente, da una buena explicación de 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 de volatile es lo que su artículo llama la "bandera de estado del patrón 1."

Si desea obtener más información sobre cómo volatile funciona bajo el capó, lea en el modelo de memoria Java. Si quieres ir más allá de ese nivel, echa un vistazo a un buen libro de arquitectura de computadoras como Hennessy & Patterson y lee sobre la coherencia de la caché y la consistencia de la caché.

 632
Author: Greg Mattes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-11 07:44:40

"... 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 usar volatile, lea el paquete java.util.concurrent que trata del comportamiento atómico.

El post de Wikipedia sobre un Patrón único muestra un uso volátil.

 148
Author: Andrew Turner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-11 07:43:16

Punto Importante acerca de volatile:

  1. La sincronización en Java es posible mediante el uso de palabras clave Java synchronized y volatile y bloqueos.
  2. En Java, no podemos tener synchronized variable. Usar la palabra clave synchronized con una variable es ilegal y dará lugar a un error de compilación. En lugar de usar la variable synchronized en Java, puede usar la variable java volatile, que le indicará a los subprocesos JVM que lean el valor de la variable volatile de la memoria principal y no lo almacenen en caché local.
  3. Si una variable no se comparte entre varios hilos, entonces no hay necesidad de usar la palabra clave volatile.

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 la instancia perezosamente en el momento en que llega la primera solicitud.

Si no hacemos la variable _instance volatile entonces el Hilo que está creando la instancia de Singleton no es capaz de comunicarse con el otro hilo. Así que si el hilo A está creando Singleton instancia y justo después de la creación, la CPU corrompe, etc., todos los demás subprocesos no podrán ver el valor de _instance como no nulo y creerán que todavía está asignado null.

¿por Qué sucede esto? Debido a que los hilos de lector no están haciendo ningún bloqueo y hasta que el hilo de escritor salga de un bloque sincronizado, la memoria no se sincronizará y el valor de _instance no se actualizará en la memoria principal. Con la palabra clave Volátil en Java, esto es manejado por Java mismo y tal las actualizaciones serán visibles por todos los hilos del lector.

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

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 comprueba el valor de la instancia una vez más dentro del bloque sincronizado (por razones de rendimiento), el compilador JIT puede reorganizar el bytecode de una manera que la referencia a la instancia se establece antes de que el constructor haya terminado su ejecución. Esto significa que el método getInstance () devuelve un objeto que puede no haber sido inicializado completamente. Para hacer que el subproceso de código sea seguro, la palabra clave volatile se puede usar desde Java 5 para la variable de instancia. Las variables que están marcadas como volátiles solo son visibles para otros subprocesos una vez que el constructor del objeto ha terminado su ejecución por completo.
Fuente

introduzca la descripción de la imagen aquí

volatile uso en Java :

Los iteradores fail-fast son típicamente implementados usando un contador volatile en el objeto list.

  • Cuando se actualiza la lista, el contador se incrementa.
  • Cuando se crea un Iterator, el valor actual del contador está incrustado en el objeto Iterator.
  • Cuando se realiza una operación Iterator, el método compara los dos valores de contador y lanza un ConcurrentModificationException si son diferentes.

La implementación de sistemas a prueba de fallos los iteradores suelen ser ligeros. Por lo general, se basan en las propiedades de las estructuras de datos de la implementación de la lista específica. No hay un patrón general.

 83
Author: Premraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-26 15:45:27

Volatile es muy útil para detener hilos.

No es que debas escribir tus propios hilos, Java 1.6 tiene un montón de buenos grupos de hilos. Pero si estás seguro de que necesitas un hilo, necesitarás 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
  }
}

Observe cómo no hay necesidad de sincronización

 44
Author: Pyrolistical,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-24 22:29:39

Un ejemplo común para usar volatile es usar una variable volatile boolean como una bandera para terminar un hilo. Si ha iniciado un hilo y desea poder interrumpirlo de forma segura desde un hilo diferente, puede hacer que el hilo verifique periódicamente una bandera. Para detenerlo, establezca la bandera en true. Al hacer la bandera volatile, puede asegurarse de que el hilo que lo está verificando verá que se ha establecido la próxima vez que lo verifique sin tener que usar un bloque synchronized.

 28
Author: Dave L.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 04:00:01

Sí, volatile debe usarse siempre que desee que múltiples hilos accedan a una variable mutable. No es un caso de uso muy común porque normalmente necesita realizar más de una sola operación atómica (por ejemplo, verificar el estado de la variable antes de modificarla), en cuyo caso usaría un bloque sincronizado en su lugar.

 12
Author: ykaganovich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 04:26:30

Nadie ha mencionado el tratamiento de la operación de lectura y escritura para tipo variable largo y doble. Las lecturas y escrituras son operaciones atómicas para las variables de referencia y para la mayoría de las variables primitivas, excepto para los tipos de variables largas y dobles, que deben usar la palabra clave volátil para ser operaciones atómicas. @ link

 12
Author: Donatello Boccaforno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-11 14:51:29

IMO dos escenarios importantes aparte de detener el hilo en el que se utiliza la palabra clave volátil son

  1. Mecanismo de bloqueo doblemente comprobado . Se utiliza a menudo en el diseño Singleton patrón. En esto el singleton object needs to be declared volatile.
  2. Wakeups espurios. El hilo a veces puede despertarse de la llamada de espera incluso si no se ha emitido ninguna llamada de notificación. Este comportamiento se llama despertar supurioso. Esto se puede contrarrestar usando una variable condicional (bandera booleana). Poner la llamada wait () en un bucle while como mientras la bandera sea verdadera. Por lo tanto, si el hilo se despierta de la llamada de espera debido a cualquier otra razón que no sea notify/notifyall, entonces se encuentra con la bandera sigue siendo verdadera y, por lo tanto, las llamadas esperan de nuevo. Antes de llamar a notify, establezca este indicador en true. En este caso, el boolean flag is declared as volatile.
 9
Author: Aniket Thakur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-25 09:17:27

Una variable declarada con la palabra clave volatile, tiene dos cualidades principales que la hacen especial.

  1. Si tenemos una variable volátil, no se puede almacenar en caché en la memoria caché del ordenador(microprocesador) por ningún hilo. El acceso siempre se realizaba desde la memoria principal.

  2. Si hay un operación de escritura pasando a la volatilidad de la variable, y de repente un operación de lectura se solicita, se garantiza que la operación de escritura estará terminado antes de la operación de lectura.

Dos cualidades anteriores deducen que

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

Y, por otro lado,

  • Si nos investigar la #2 que he mencionado, podemos ver que volatile la palabra clave es una forma ideal de mantener una variable compartida que tiene 'n' número de hilos de lectura y solo un hilo de escritura para acceder a él. Una vez que agregamos la palabra clave volatile, se hace. No hay ningún otro sobrecarga sobre la seguridad del hilo.

Conversly,

Nosotros no puedo hacer uso de la palabra clave volatile únicamente, para satisfacer una variable compartida que tiene más de un subproceso de escritura accediendo a él.

 8
Author: Supun Wijerathne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-23 02:28:48

Necesitará usar la palabra clave 'volatile', o 'synchronized' y cualquier otra herramienta y técnica de control de concurrencia que pueda tener a su disposición si está desarrollando una aplicación multiproceso. Ejemplo de dicha aplicación es aplicaciones de escritorio.

Si está desarrollando una aplicación que se implementaría en el servidor de aplicaciones (Tomcat, JBoss AS, Glassfish, etc.), no tiene que manejar el control de concurrencia usted mismo, ya que ya lo ha abordado el servidor de aplicaciones. De hecho, si recordado correctamente el estándar Java EE prohíbe cualquier control de concurrencia en servlets y EJBs, ya que es parte de la capa de 'infraestructura' que se supone que se libera de manejarlo. Solo realiza control de concurrencia en dicha aplicación si está implementando objetos singleton. Esto incluso ya se ha abordado si tejes tus componentes usando frameworkd como Spring.

Por lo tanto, en la mayoría de los casos de desarrollo Java donde la aplicación es una aplicación web y el uso de IOC framework como Spring o EJB, no necesitarías usar 'volátil'.

 5
Author: Rudi Adianto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-10 18:02:44

volatile solo garantiza que todos los hilos, incluso ellos mismos, están aumentando. Por ejemplo: un contador ve la misma cara de la variable al mismo tiempo. No se usa en lugar de sincronizado o atómico u otras cosas, hace que las lecturas estén completamente sincronizadas. Por favor, no lo compare con otras palabras clave java. Como muestra el ejemplo a continuación, las operaciones de variables volátiles también son atómicas, fallan o tienen éxito a la vez.

package io.netty.example.telnet;

import java.util.ArrayList;
import java.util.List;

public class Main {

    public static volatile  int a = 0;
    public static void main(String args[]) throws InterruptedException{

        List<Thread> list = new  ArrayList<Thread>();
        for(int i = 0 ; i<11 ;i++){
            list.add(new Pojo());
        }

        for (Thread thread : list) {
            thread.start();
        }

        Thread.sleep(20000);
        System.out.println(a);
    }
}
class Pojo extends Thread{
    int a = 10001;
    public void run() {
        while(a-->0){
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Main.a++;
            System.out.println("a = "+Main.a);
        }
    }
}

Incluso si pones resultados volátiles o no siempre diferirán. Pero si utiliza AtomicInteger como a continuación los resultados serán siempre los mismos. Esto es lo mismo con sincronizado también.

    package io.netty.example.telnet;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicInteger;

    public class Main {

        public static volatile  AtomicInteger a = new AtomicInteger(0);
        public static void main(String args[]) throws InterruptedException{

            List<Thread> list = new  ArrayList<Thread>();
            for(int i = 0 ; i<11 ;i++){
                list.add(new Pojo());
            }

            for (Thread thread : list) {
                thread.start();
            }

            Thread.sleep(20000);
            System.out.println(a.get());

        }
    }
    class Pojo extends Thread{
        int a = 10001;
        public void run() {
            while(a-->0){
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Main.a.incrementAndGet();
                System.out.println("a = "+Main.a);
            }
        }
    }
 5
Author: fatih tekin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-18 15:06:14

Sí, lo uso bastante - puede ser muy útil para código multihilo. El artículo que apuntaste es bueno. Aunque hay dos cosas importantes a tener en cuenta:

  1. Solo debe usar volátil si entender completamente lo que hace y cómo se diferencia de sincronizado. En muchas situaciones aparece volátil, en la superficie, para ser un más simple alternativa performante a sincronizado, cuando a menudo un mejor comprensión de volátil haría claro que sincronizado es el único opción que funcionaría.
  2. volátil en realidad no funciona en un muchos JVM más viejos, aunque sincronizado lo hace. Recuerdo haber visto un documento que hacía referencia a los diversos niveles de soporte en diferentes JVM, pero desafortunadamente no puedo encontrarlo ahora. Definitivamente mira si estás usando Java pre 1.5 o si no tienes control sobre las JVM en las que se ejecutará tu programa.
 4
Author: MB.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 11:07:48

Absolutamente, sí. (Y no solo en Java, sino también en C#.) Hay momentos en los que necesita obtener o establecer un valor que se garantiza que sea una operación atómica en su plataforma dada, un int o booleano, por ejemplo, pero no requiere la sobrecarga de bloqueo de rosca. La palabra clave volatile te permite asegurarte de que cuando leas el valor obtienes el actual y no un valor almacenado en caché que acaba de quedar obsoleto por una escritura en otro hilo.

 3
Author: dgvid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-06 14:28:48

Cada subproceso que acceda a un campo volátil leerá su valor actual antes de continuar, en lugar de (potencialmente) usar un valor almacenado en caché.

Solo la variable miembro puede ser volátil o transitoria.

 3
Author: tstuber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-11 16:27:12

Hay dos usos diferentes de la palabra clave volátil.

  1. Evita que JVM lea valores desde el registro (asumir como caché), y obliga a que su valor se lea desde la memoria.
  2. Reduce el riesgo de errores de consistencia de la memoria.

Evita que JVM lea valores en el registro, y obliga a su valor a leer de la memoria.

Un indicador de ocupado se usa para evitar que un hilo continúe mientras el dispositivo está ocupado y el indicador no protegido por un candado:

while (busy) {
    /* do something else */
}

El hilo de prueba continuará cuando otro hilo desactive la bandera ocupado :

busy = 0;

Sin embargo, dado que busy se accede con frecuencia en el subproceso de prueba, la JVM puede optimizar la prueba colocando el valor de busy en un registro, luego probar el contenido del registro sin leer el valor de busy en la memoria antes de cada prueba. El subproceso de prueba nunca vería el cambio de ocupado y el otro subproceso solo cambiaría el valor de ocupado en memoria, lo que resulta en un punto muerto. Declarar la bandera ocupado como volátil obliga a leer su valor antes de cada prueba.

Reduce el riesgo de errores de consistencia de memoria.

El uso de variables volátiles reduce el riesgo de errores de consistencia de memoria , porque cualquier escritura en una variable volátil establece una "sucede-antes" relación con lecturas posteriores de esa misma variable. Esto significa que los cambios en una variable volátil son siempre visible para otros hilos.

La técnica de leer, escribir sin errores de consistencia de memoria se llama acción atómica.

Una acción atómica es aquella que efectivamente sucede de una sola vez. Una acción atómica no puede detenerse en el medio: o sucede completamente, o no sucede en absoluto. No hay efectos secundarios de una acción atómica son visibles hasta que la acción es completa.

A continuación se muestran las acciones que puede especificar que son atómicas:

  • Lee y escribe son atómico para variables de referencia y para la mayoría variables primitivas (todos los tipos excepto long y double).
  • Las lecturas y las escrituras son atómicas para todas las variables declaradas volátiles (incluyendo variables largas y dobles).

Salud!

 2
Author: dheeran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-02 08:42:57

Las variables volátiles son una sincronización ligera. Cuando la visibilidad de los datos más recientes entre todos los hilos es un requisito y la atomicidad puede verse comprometida, en tales situaciones se deben preferir variables volátiles. Las variables volátiles siempre devuelven la escritura más reciente realizada por cualquier subproceso, ya que no se almacenan en caché en registros ni en cachés donde otros procesadores no pueden ver. Volatile está Libre de Bloqueos. Utilizo volátil, cuando el escenario cumple con los criterios mencionados anteriormente.

 2
Author: Neha Vari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-06 12:57:06

De la página de documentación de oracle , surge la necesidad de variables volátiles para solucionar problemas de consistencia de memoria:

El uso de variables volátiles reduce el riesgo de errores de consistencia de la memoria, porque cualquier escritura en una variable volátil establece una relación sucede-antes con lecturas posteriores de esa misma variable.

Esto significa que los cambios a una variable volatile son siempre visibles para otros subprocesos. También significa que cuando un hilo lee un volátil variable, no solo ve el último cambio en el volatile, sino también los efectos secundarios del código que condujo al cambio.

Como se explica en la respuesta Peter Parker, en ausencia del modificador volatile, la pila de cada hilo puede tener su propia copia de variable. Al convertir la variable en volatile, se han solucionado los problemas de consistencia de la memoria.

Echa un vistazo a jenkov página tutorial para una mejor comprensión.

Eche un vistazo a la pregunta SE relacionada para obtener más detalles sobre volátil & casos de uso para usar volatile:

Diferencia entre volátil y sincronizado en Java

Un caso de uso práctico:

Tiene muchos hilos, que necesitan imprimir la hora actual en un formato particular, por ejemplo : java.text.SimpleDateFormat("HH-mm-ss"). Yon puede tener una clase, que convierte el tiempo actual en SimpleDateFormat y actualiza la variable por cada segundo. Todos los demás hilos pueden simplemente usar esta variable volátil para imprimir la hora actual en archivos de registro.

 1
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:55:13

Una variable volátil se modifica de forma asíncrona ejecutando subprocesos simultáneamente en una aplicación Java. No está permitido tener una copia local de una variable que sea diferente del valor que se encuentra actualmente en la memoria "principal". Efectivamente, una variable declarada volátil debe tener sus datos sincronizados en todos los subprocesos, de modo que cada vez que acceda o actualice la variable en cualquier subproceso, todos los demás subprocesos vean inmediatamente el mismo valor. Por supuesto, es probable que las variables volátiles tener un mayor acceso y sobrecarga de actualización que las variables "simples", ya que la razón por la que los hilos pueden tener su propia copia de datos es para una mejor eficiencia.

Cuando un campo es declarado volátil, el compilador y el tiempo de ejecución son advertidos de que esta variable es compartida y que las operaciones en ella no deben ser reordenadas con otras operaciones de memoria.Las variables volátiles no se almacenan en caché en registros o en cachés donde se ocultan a otros procesadores, por lo que una lectura de un la variable volátil siempre devuelve la escritura más reciente de cualquier hilo.

Para referencia, refiérase a esto http://techno-terminal.blogspot.in/2015/11/what-are-volatile-variables.html

 0
Author: satish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-17 09:36:43

La clave volátil cuando se usa con una variable, se asegurará de que los hilos que lean esta variable vean el mismo valor . Ahora, si tiene varios hilos leyendo y escribiendo en una variable, hacer que la variable sea volátil no será suficiente y los datos estarán dañados . Los subprocesos de imagen han leído el mismo valor, pero cada uno ha hecho algunos cambios (por ejemplo , aumentó un contador), al escribir de nuevo en la memoria, se viola la integridad de los datos . Es por eso que es necesario hacer que la variable sincronizado (formas diferentes son posibles)

Si los cambios se realizan por 1 hilo y los demás solo necesitan leer este valor, el volátil será adecuado.

 0
Author: Java Main,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-24 16:41:21

Volatile hace lo siguiente.

1> La lectura y escritura de variables volátiles por diferentes subprocesos son siempre desde la memoria, no desde la propia caché del subproceso o el registro de cpu. Así que cada hilo siempre trata con el último valor. 2 > Cuando 2 subprocesos diferentes trabajan con la misma instancia o variables estáticas en heap, uno puede ver las acciones de otros como fuera de orden. Ver el blog de Jeremy manson sobre esto. Pero volátil ayuda aquí.

Siguiendo el código en ejecución completa se muestra cómo un número de subprocesos puede ejecutarse en orden predefinido y salidas de impresión sin utilizar palabra clave sincronizada.

thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3
thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3
thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3

Para lograr esto podemos usar el siguiente código de ejecución completo.

public class Solution {
    static volatile int counter = 0;
    static int print = 0;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Thread[] ths = new Thread[4];
        for (int i = 0; i < ths.length; i++) {
            ths[i] = new Thread(new MyRunnable(i, ths.length));
            ths[i].start();
        }
    }
    static class MyRunnable implements Runnable {
        final int thID;
        final int total;
        public MyRunnable(int id, int total) {
            thID = id;
            this.total = total;
        }
        @Override
        public void run() {
            // TODO Auto-generated method stub
            while (true) {
                if (thID == counter) {
                    System.out.println("thread " + thID + " prints " + print);
                    print++;
                    if (print == total)
                        print = 0;
                    counter++;
                    if (counter == total)
                        counter = 0;
                } else {
                    try {
                        Thread.sleep(30);
                    } catch (InterruptedException e) {
                        // log it
                    }
                }
            }
        }
    }
}

El siguiente enlace de github tiene un readme, que da una explicación adecuada. https://github.com/sankar4git/volatile_thread_ordering

 0
Author: sankar banerjee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-31 06:23:43

Me gusta la explicación de jenkov

La palabra clave Java volatile se usa para marcar una variable Java como "almacenada en la memoria principal". Más precisamente, eso significa que cada lectura de una variable volátil se leerá desde la memoria principal del equipo, y no desde la caché de la CPU, y que cada escritura en una variable volátil se escribirá en la memoria principal, y no solo en la caché de la CPU.

En realidad, desde Java 5 la palabra clave volátil garantiza más que eso las variables volátiles se escriben y leen desde la memoria principal. Es la garantía extendida de la visibilidad pasa así llamado-antes de la garantía.

Consideraciones de rendimiento de volatile

La lectura y escritura de variables volátiles hace que la variable sea leída o escrita en la memoria principal. Leer y escribir en la memoria principal es más caro que acceder a la caché de la CPU. El acceso a variables volátiles también evita el reordenamiento de instrucciones, que es un rendimiento normal técnica de mejora. Por lo tanto, solo debe usar variables volátiles cuando realmente necesite reforzar la visibilidad de las variables.

 0
Author: yoAlex5,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-16 14:16:55