I'd like to clarify how happens-before relation works with volatile variables. Let we have the following variables:
public static int i, iDst, vDst;
public static volatile int v;
and thread A:
i = 1;
v = 2;
and thread B:
vDst = v;
iDst = i;
Are the following statements correct in accordance with Java memory model (JMM)? If not, what would be correct interpretation?
i = 1
always happens-before v = 2
v = 2
happens-before vDst = v
in JMM only if it's actually happens before in timei = 1
happens-before iDst = i
in JMM (and iDst
will be predictably assigned 1
) if v = 2
actually happens before vDst = v
in timei = 1
and iDst = i
is undefined and resulting value of iDst
is undefined as wellMistake in the logic:
There is no "wall clock time" concept in JMM, and we should rely on synchronization order as an ordering guide for v = 2
and vDst = v
. See the chosen answer for further details.
i = 1
always happens-before v = 2
True. By JLS section 17.4.5,
If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
v = 2
happens-before vDst = v
in JMM only if it's actually happens before in timei = 1
happens-before iDst = i
in JMM (and iDst
will be predictably assigned 1
) if v = 2
actually happens before vDst = v
in timeFalse. The happens-before order does not make guarantees about things happening before each other in physical time. From the same section of the JLS,
It should be noted that the presence of a happens-before relationship between two actions does not necessarily imply that they have to take place in that order in an implementation. If the reordering produces results consistent with a legal execution, it is not illegal.
It is, however, guaranteed that v = 2
happens-before vDst = v
and i = 1
happens-before iDst = i
if v = 2
comes before vDst = v
in the synchronization order, a total order over the synchronization actions of an execution that is often mistaken for the real-time order.
i = 1
and iDst = i
is undefined and resulting value of iDst
is undefined as wellThis is the case if vDst = v
comes before v = 2
in the synchronization order, but actual time doesn't come into it.