variable tipo sincronizados metodos atributo atomicas java multithreading

tipo - ¿Tiene Java la escritura de descarga de lectura volátil y hace la lectura de actualización de escritura volátil



variable volatile java (4)

Entiendo la lectura-adquisición (no se reordena con las operaciones de lectura / escritura posteriores), y la escritura-liberación (no se reordena con las operaciones de lectura / escritura que la preceden) Mi q es: -

  1. En caso de lectura-adquisición, ¿se borran las escrituras que la preceden?
  2. En caso de escritura-liberación, ¿se actualizan las lecturas anteriores?

Además, ¿la lectura se adquiere igual que la lectura volátil y la versión de escritura es igual que la escritura volátil en Java?

Por qué esto es importante es que, tomemos el caso de la versión de escritura ...

y = x; // a read.. let''s say x is 1 at this point System.out.println(y);// 1 printed //or you can also consider System.out.println(x); write_release_barrier(); //somewhere here, some thread sets x = 2 ready = true;// this is volatile System.out.println(y);// or maybe, println(x).. what will be printed?

En este punto, es x 2 o 1? Aquí, considere listo para ser volátil. Entiendo que todas las tiendas antes de la volatilidad se harán visibles primero ... y luego solo la volatilidad se hará visible. Gracias.

Ref: - http://preshing.com/20120913/acquire-and-release-semantics/


El modelo de memoria Java no se especifica en términos de "lectura-adquisición" y "escritura-liberación". Estos términos / conceptos provienen de otros contextos, y como el artículo al que hace referencia lo deja muy claro, a menudo son utilizados (por expertos diferentes) para significar cosas diferentes.

Si desea comprender cómo funcionan los volátiles en Java, debe comprender el modelo de memoria de Java y la terminología de Java ... que (afortunadamente) está bien fundamentada y se especifica con precisión 1 . Tratar de asignar el modelo de memoria Java a la semántica de "lectura-adquisición" y "escritura-liberación" es una mala idea porque:

  • La terminología y la semántica de "lectura-adquisición" y "escritura-liberación" no están bien especificadas, y

  • un hipotético JMM -> "lectura-adquisición" / "escritura-liberación" mapeo semántico es solo una posible implementación de JMM. Otras asignaciones pueden existir con semánticas diferentes e igualmente válidas .

1 - ... módulo que los expertos han notado fallas en algunas versiones de la JMM. Pero el punto es que se ha intentado seriamente proporcionar una especificación teóricamente sólida ... como parte de la Especificación del lenguaje Java.


No, la lectura de una variable volátil no borrará escrituras anteriores. Las acciones visibles asegurarán que las acciones anteriores sean visibles, pero la lectura de una variable volátil no es visible en otros subprocesos.

No, escribir en una variable volátil no borrará el caché de los valores leídos previamente. Sólo está garantizado para borrar escrituras anteriores.

En su ejemplo, claramente y aún será 1 en la última línea. Sólo se ha realizado una asignación a y , que era 1, según la salida anterior. Quizás ese fue un error tipográfico, y usted quería escribir println(x) , pero incluso en ese caso, no se garantiza que el valor de 2 sea visible.


No: no se borran todas las escrituras, ni se actualizan todas las lecturas.

Java funciona sobre una base de "sucede antes" para multiproceso. Básicamente, si A sucede antes de B y B ocurre antes de C, entonces A ocurre antes de C. Así que su pregunta equivale a si x=2 ocurre formalmente antes de alguna acción que diga x.

Básicamente, antes de que los bordes se establezcan mediante las relaciones sincroniza con, que se definen en JLS 17.4.4 . Hay algunas maneras diferentes de hacer esto, pero para volátiles, básicamente equivale a una escritura para que ocurra una volatilidad, antes de una lectura de esa misma volatilidad:

  • Una escritura en una variable volátil v (§8.3.1.4) se sincroniza con todas las lecturas subsiguientes de v por cualquier hilo (donde "subsiguiente" se define de acuerdo con el orden de sincronización).

Dado que, si tu hilo está ready = true , entonces solo escribir no significa que ocurra nada antes de eso (en lo que concierne a esa escritura). En realidad es lo contrario; que escriban para que ready , antes de que aparezcan en otros subprocesos, si están ready leer.

Por lo tanto, si el otro subproceso (que establece x = 2 ) se haya escrito listo después de que establezca x = 2 , y este subproceso (que usted publicó anteriormente) se haya ready , verá que x = 2 . Esto se debe a que la escritura ocurre antes de la lectura y, por lo tanto, el hilo de lectura ve todo lo que el hilo de escritura había hecho (hasta e incluso la escritura). De lo contrario, tienes una carrera de datos, y básicamente todas las apuestas están apagadas.

Un par de notas adicionales:

  • Si no tiene un borde anterior, puede que aún vea la actualización; Es solo que no tienes garantía de hacerlo. Entonces, no asumas que si no lees una escritura para ready , entonces verás x = 1. Es posible que vea x = 1, o x = 2, o posiblemente alguna otra escritura (hasta e incluyendo el valor predeterminado de x = 0)
  • En su ejemplo, y siempre va a ser 1, porque no vuelve a leer x después del comentario "en algún lugar aquí". Para los propósitos de esta respuesta, asumí que hay una segunda línea y=x inmediatamente antes o después de ready = true . Si no lo hay, entonces el valor de y no se modificará respecto de lo que era en la primera println , (suponiendo que ningún otro hilo lo cambie directamente, lo que está garantizado si es una variable local), porque las acciones dentro de un hilo siempre aparecen como si fueran no reordenado

Para su primera pregunta, la respuesta es que orden FIFO

Para su segunda pregunta: compruebe por favor Volatile Vs Static en java