2012-02-08 14 views
10

En Java, con mi conocimiento, la variable volátil hace que un hilo lea/escriba directamente en la CPU principal (no en el caché de cada hilo), por lo que su cambio se ve a otros hilos.Volátil: por qué prevenir el código de reordenación del compilador

Lo que no sé es: Entonces, ¿por qué este trabajo (de volátil) puede evitar la declaración de código del compilador/CPU?

gracias :)

+0

Tenga en cuenta que esto acerca de las lecturas volátiles evita las cachés es una construcción puramente teórica y realmente no tiene mucho que ver con lo que 'volátil 'realmente tiene en el hardware real. Simplemente imaginamos que hay todo tipo de cosas que una implementación podría hacer y que 'volátil 'garantiza que las optimizaciones no producen comportamientos particulares que debemos prohibir en casos particulares. –

Respuesta

16

Aquí es un muy buen ejemplo que ilustra el tema de la prohibición de reordenamiento está dirigido a tratar (tomado de here):

class VolatileExample { 
    int x = 0; 
    volatile boolean v = false; 
    public void writer() { 
     x = 42; 
     v = true; 
    } 
    public void reader() { 
     if (v == true) { 
      //uses x - guaranteed to see 42. 
     } 
    } 
} 

En este ejemplo, v es volátil, pero no es x. Si el escritor y el lector se ejecutan al mismo tiempo y el lector ve v establecido en true, x se garantiza que es 42. Antes de Java 5, compilador era libre de volver a ordenar las escrituras en x y v, por lo que podía ver x en cero después de has visto v conjunto de true. Esto fue confuso y condujo a errores sutiles. El modelo de memoria Java-5 solucionó este problema al hacer que las escrituras volátiles fueran casi equivalentes a la sincronización.

+1

No veo cómo se garantiza el lector, vea x en 42. Claro que x = 42 puede ocurrir antes de que v = verdadero, pero el lector() todavía podría ver un valor en la memoria caché de 0, ¿no? – Shawn

+1

@Shawn Hasta que Java-5 fue correcto, pero el modelo de memoria Java-5 se asegura de que todas las escrituras se completen antes de la escritura volátil. Ver enlace para más detalles. – dasblinkenlight

+0

gracias, es bueno saberlo! – Shawn

5

Eso es sólo cómo se define el lenguaje. Informalmente, marcar una variable volatile en Java le dice específicamente al compilador que no debe reordenar las instrucciones a su alrededor u optimizar su valor, ya que ese valor podría modificarse simultáneamente en otro hilo. La implementación particular de la JVM es entonces responsable de respetar este modificador volatile y tomar las precauciones adecuadas para no optimizar el programa incorrectamente.

Si desea obtener más detalles sobre las garantías de nivel de idioma para asegurar que volatile funciona correctamente, le recomendamos que consulte the Java Language Specification's description of the Java memory model, que define las reglas abstractas que rigen el comportamiento de la secuencia. También describe cómo interactúa volatile con estas reglas.

Espero que esto ayude!

Cuestiones relacionadas