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; } }The assignments of
one,twoandthreemay be reordered, as long as they all happen before thevolatilewrite. Similarly, thex,y, andzstatements may be reordered as thevolatilewrite happens before all of them. Thevolatileoperation is often called a memory barrier. The happens before guarantee ensures that read and write instructions ofvolatilevariables cannot be reordered across a memory barrier.The happens before guarantee has another effect: When a thread writes to a
volatilevariable, then all other variables - including non-volatiles - changed by the thread before writing to thevolatilevariable are also flushed to main memory. When a thread reads avolatilevariable it also reads all other variables - including non-volatile - that were flushed to main memory together with thevolatilevariable.
© Bruce Eckel "On Java 8"
I must have misunderstood something because this code doesn't work like this
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();
}
}
}
I think, the problem can occur when the writer tread has just set x=1, while the reader is already in the if block (before the variable assignments):
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With