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.
For Java, “volatile” tells the compiler that the value of a variable must never be cached as its value may change outside of the scope of the program itself.
The Java happens before guarantee is a set of rules that govern how the Java VM and CPU is allowed to reorder instructions for performance gains.
The volatile modifier is used to let the JVM know that a thread accessing the variable must always merge its own private copy of the variable with the master copy in the memory. Accessing a volatile variable synchronizes all the cached copied of the variables in the main memory.
Volatile fields are instance or class (static) variables and are stored in the heap.
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.
Yes all of them are correct according to this section about happens-before order:
i = 1
always happens-before v = 2
since: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 time, since v
is volatile, and A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.
i = 1
happens-before iDst = i
in JMM (and iDst
will be predictably assigned 1) if v = 2
actually happens before vDst = v
in time. This is because in this case: i = 1
happens-before v = 2
v = 2
happens-before vDst = v
vDst = v
happens-before iDst = i
If hb(x, y) and hb(y, z), then hb(x, z).
EDIT:
As argued by @user2357112, it seems statements 2 and 3 are not accurately correct. The happens-before relationship does not necessarily impose a timing order between actions having this relationship, as mentioned in 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.
Therefore, in terms of the rules mentioned in the JLS, we shouldn't make assumptions on the actual timing of the execution of the statements.
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