In discussion at Does a correctly synchronized program still allow data race?(Part I), we got two very good examples.
I just want to discuss the second one. For convenience, I just put second example at here:
public int hashCode() {
if (hash == 0 && count > 0) { //(1)
int h = hash;
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h; //(2)
}
return hash; //(3)
}
According to fist item in definition of happens-before relationship: If x and y are actions of the same thread and x comes before y in program order, then hb(x, y), we may get following conclusion:
there are hb((1),(2)) and hb((2),(3)), hence hb((1),(3)).
Because:
hash is a shared variable;
(1),(2),(3) are all actions of the same thread;
(1) comes before (2), (2) comes before (3) in program order.
Now back to my question: if there is a happens-before relationship between (1) and (3), then (1) and (3) should never be reordered.
Is there any misunderstanding in my explanation? How about your opinion?