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?
println
is a synchronized method - so whatever you're testing is going to benefit from that additional synchronization. You could probably remove the volatile keyword and get the same result (depending on your CPU etc.)... – Remonstrance1, 0
? The fields are initialized to0
, then at some time later assigned1
. – Darnvolatile
is not specified in terms of memory barriers. If you want a deep understanding ofvolatile
and Java thread synchronization in general, read the Java Language Specification. – Orcinolstore(g, 1)
beforestore(x,1)
" is not a valid optimisation (it would not comply with the volatile semantics). – Remonstrance1,0
However it's really only for this exact sort of case and also making some assumptions about what is being asked here. It could be in other very similar situations that it's legal, even expected, to see something like1,0
. – Worldwide