So I am reading this book titled Java Concurrency in Practice and I am stuck on this one explanation which I cannot seem to comprehend without an example. This is the quote:
When thread
A
writes to a volatile variable and subsequently threadB
reads that same variable, the values of all variables that were visible toA
prior to writing to the volatile variable become visible toB
after reading the volatile variable.
Can someone give me a counterexample of why "the values of ALL variables that were visible to A
prior to writing to the volatile variable become visible to B
AFTER reading the volatile variable"?
I am confused why all other non-volatile variables do not become visible to B
before reading the volatile variable?
Volatile is a qualifier that is applied to a variable when it is declared. It tells the compiler that the value of the variable may change at any time-without any action being taken by the code the compiler finds nearby. The implications of this are quite serious.
A volatile variable is a variable that is marked or cast with the keyword "volatile" so that it is established that the variable can be changed by some outside factor, such as the operating system or other software.
The volatile memory stores data and computer programs that the CPU may need in real-time, and it erases them once a user switches off the computer. Cache memory and RAM are types of Volatile memory. Non-volatile memory, on the other hand, is static. It remains in a computer even after a user switches it off.
Volatile fields are instance or class (static) variables and are stored in the heap.
Declaring a volatile Java variable means:
Just for your reference, When is volatile needed ?
When multiple threads using the same variable, each thread will have its own copy of the local cache for that variable. So, when it's updating the value, it is actually updated in the local cache not in the main variable memory. The other thread which is using the same variable doesn't know anything about the values changed by the another thread. To avoid this problem, if you declare a variable as volatile, then it will not be stored in the local cache. Whenever thread are updating the values, it is updated to the main memory. So, other threads can access the updated value.
From JLS §17.4.7 Well-Formed Executions
We only consider well-formed executions. An execution E = < P, A, po, so, W, V, sw, hb > is well formed if the following conditions are true:
Each read sees a write to the same variable in the execution. All reads and writes of volatile variables are volatile actions. For all reads r in A, we have W(r) in A and W(r).v = r.v. The variable r.v is volatile if and only if r is a volatile read, and the variable w.v is volatile if and only if w is a volatile write.
Happens-before order is a partial order. Happens-before order is given by the transitive closure of synchronizes-with edges and program order. It must be a valid partial order: reflexive, transitive and antisymmetric.
The execution obeys intra-thread consistency. For each thread t, the actions performed by t in A are the same as would be generated by that thread in program-order in isolation, with each write wwriting the value V(w), given that each read r sees the value V(W(r)). Values seen by each read are determined by the memory model. The program order given must reflect the program order in which the actions would be performed according to the intra-thread semantics of P.
The execution is happens-before consistent (§17.4.6).
The execution obeys synchronization-order consistency. For all volatile reads r in A, it is not the case that either so(r, W(r)) or that there exists a write win A such that w.v = r.v and so(W(r), w) and so(w, r).
Useful Link : What do we really know about non-blocking concurrency in Java?
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