I recently heard in a talk that a write to a volatile triggers a memory-barrier for each variable that the thread has written to. Is that really correct? From the JLS, it seems that only the variable concerned gets flushed out, but not others. Does anybody know what is actually correct? Can one point me a concrete location in the JLS?
-
1My interpretation of the JLS agrees with yours. – NPE Dec 03 '12 at 17:40
-
2possible duplicate of [Volatile variables and other variables](http://stackoverflow.com/questions/12438464/volatile-variables-and-other-variables) – assylias Dec 03 '12 at 17:47
-
As the answer clarifies, it's not just the variable that's declared as volatile but all writes that happened before the volatile write. – sjlee Dec 03 '12 at 17:59
2 Answers
Yes, it will initiate a barrier. You can read more here. There are 4 types, LoadLoad LoadStore StoreStore StoreLoad.
As far as your question
From the JLS, it seems that only the variable concerned gets flushed out, but not others. Does anybody know what is actually correct?
All writes that occur before a volatile store are visible by any other threads with the predicate that the other threads load this new store. However, writes that occur before a volatile load may or may not be seen by other threads if they do not load the new value.
For a practical example
volatile int a =0;
int b = 0;
Thread-1
b = 10;
a = 3;
Thread-2
if(a == 0){
// b can b 10 or 0
}
if(a == 3){
// b is guaranteed to be 10 (according to the JMM)
}

- 39,695
- 7
- 78
- 108
-
2
-
4I think your example is wrong. Thread-2 doesn't need to compare `a` to 3 to see the new value of `b`, it is sufficient to read `a`. So immediately after the first line, Thread-2 is guaranteed to see `b` equal to 10 (in all branches). However, a third thread which never reads `a` is not guaranteed to see the new value of `b`. – Philipp Wendler Dec 03 '12 at 18:17
-
14@PhilippWendler I think the point was: if a == 0, the write `a = 3` has not happened yet and b can be anything, including 10. if a == 3, the write `a = 3` has happened and you are guaranteed to have b == 10. – assylias Dec 03 '12 at 18:38
-
Shouldn't this be clarified with a better codediagram showing the time beside the code? e.g. t=0, t=1, t=2, t=3... – Pacerier Aug 11 '14 at 08:11
-
@assylias which one is correct? Looks like Philipp's comment is right according to JLS. If not can you please point to the right sentence in the JLS. My understanding is that a==0 statement will definitely load/see a as 3 which is the new store and hence b as 10 from this point onwards. – user104309 Mar 14 '17 at 05:36
-
@assylias My bad.Got it. My assumption was a=3 happened before a==0. Didn't realize if a==0 condition in Thread-2 is satisfied then a=3 was not done in Thread-1 (How am I sure that a=3 didn't happen in Thread-1 if a==0 is satisfied? If a=3 happened,then at a==0 a will be 3 for sure since it is volatile and the condition won't be satisfied) and hence a volatile write has not happened and hence all writes before it (that is, b=10) need not necessarily be visible at volatile read. – user104309 Mar 14 '17 at 06:54
The reference to Volatile variables and other variables was correct. I did not realize that the transitivity of happens-before is something that must be implemented by the VM, not something that follows from the definition. I am still puzzled why something with so far-reaching consequences is not stated clearly but actually a corollary from some definition. To wrap it up: Suppose you have 4 actions like this:
thread1 thread2
a1
a2
a3
a4
where a2 is a write to a volatile variable v and a3 is a read from the same volatile variable v. It follows from the definiton of happens-before (hb) that hb(a1,a2) and hb(a3,a4). Also, for volatiles we have hb(a2,a3). It follows now from the required transitivity of hb that hb(a1,a3). So the write and subsequent read of the volatile variable v functions as a memory barrier.