public class ReOrdering implements Runnable { int one, two, three, four, five, six; volatile int volaTile; @Override public void run() { one = 1; two = 2; three = 3; volaTile = 92; int x = four; int y = five; int z = six; } }
Las asignaciones de
one
,two
ythree
pueden ser reordenadas, siempre y cuando todos ellos ocurren antes de lavolatile
escritura. Del mismo modo, lasx
,y
yz
declaraciones pueden ser reordenadas como lavolatile
escritura ocurre antes de todos ellos. Lavolatile
operación es a menudo llamado un barrera de memoria . La garantía asegura que sucede antes de que leen y las instrucciones de escritura devolatile
variables que no se pueden reordenar a través de una barrera de memoria .La garantía de que ocurre antes tiene otro efecto: Cuando un hilo escribe a una
volatile
variable, entonces todas las otras variables - incluyendo los no volátiles - cambiadas por el hilo antes de escribir a lavolatile
variable también se vuelcan a la memoria principal. Cuando un hilo lee unavolatile
variable de también lee todas las otras variables - incluyendo no volátil - que fueron enrojecida a la memoria principal, junto con lavolatile
variable.
© Bruce Eckel "En Java 8"
Debo haber entendido mal algo porque el código no funciona como esto
public class Reordering {
private int x;
private volatile int y;
public void writer() {
x = 1;
y = 2;
}
public void reader() {
if (y == 2) {
if(x == 0) {
// X assignment is happens-before for
// volatile Y assignment
// so X can't be 0 when Y equals 2
throw new RuntimeException();
}
x = 0;
y = 0;
}
}
public static void main(String[] args) {
Reordering reordering = new Reordering();
Thread thread = new Thread(() -> {
while (true) {
reordering.writer();
}
});
thread.setDaemon(true);
thread.start();
while (true) {
reordering.reader();
}
}
}
Creo, el problema se da cuando la banda de rodadura escritor acaba de establecer x=1
, mientras que el lector ya está en el bloque if (antes de las asignaciones de variables):
reader writer state
----------------- ------ --------
stops before x=0 x=1, y=2
x=1 x=1, y=2
x=0 x=0, y=2
y=0 x=0, y=0
y=2 x=0, y=2
reader will throw