Does Java allows output 1, 0? I've tested it very intensively and I cannot get that output. I get only 1, 1 or 0, 0 or 0, 1.
public class Main {
private int x;
private volatile int g;
// Executed by thread #1
public void actor1(){
x = 1;
g = 1;
}
// Executed by thread #2
public void actor2(){
put_on_screen_without_sync(g);
put_on_screen_without_sync(x);
}
}
Why?
On my eye it is possible to get 1, 0. My reasoning.
g is volatile so it causes that memory order will be ensured. So, it looks like:
actor1:
(1) store(x, 1)
(2) store(g, 1)
(3) memory_barrier // on x86
and, I see the following situation:
reorder store(g, 1) before store(x,1) (memory_barrier is after (2)).
Now, run thread #2. So, g = 1, x = 0. Now, we have expected output.
What is incorrect in my reasoning?
解决方案
Any actions before a volatile write happen before (HB) any subsequent volatile read of the same variable. In your case, the write to x happens before the write to g (due to program order).
So there are only three possibilities:
actor2 runs first and x and g are 0 - output is 0,0
actor1 runs first and x and g are 1 because of the happens before relationship HB - output is 1,1
the methods run concurrently and only x=1 is executed (not g=1) and the output could be either 0,1 or 0,0 (no volatile write so no guarantee)