I think I understand the happened-before relationship for single variables. If I write a volatile field, all subsequent reads of this field will contain this new value. Writing a volatile
crosses the memory barrier and flushes new value to main memory.
I still am not clear on what happens in all other cases - for instance Thread.start()
, synchronized
or new locks in java.util.concurrent
. What does it mean that they also cross memory barrier? What data is flushed from local cache to main memory? In other words, what is the scope of the crossing?
Is everything always flushed? Now back to volatile
, does it flush more than just the single volatile
field?
Memory barriers, or fences, are a set of processor instructions used to apply ordering limitations on memory operations.
Java memory model is divided between Thread Stacks (One for each thread) and a heap area. Thread Stack: It is a thread specific memory area and contains local variables, methods call information etc. JVM stacks could be of fixed size or variable size.
The memory barrier instructions halt execution of the application code until a memory write of an instruction has finished executing. They are used to ensure that a critical section of code has been completed before continuing execution of the application code.
Memory barriers are necessary because most modern CPUs employ performance optimizations that can result in out-of-order execution.
When a memory barrier is crossed JVM synchronizes all locally (in context of the current thread) cached variables with the main memory. Besides that, it removes any locally cached data that is marked as dirty in the main memory.
Regarding the volatile - yes, it also synchronizes everything locally cached with the main memory, not only the single volatile field (since 1.5)
http://www.javamex.com/tutorials/synchronization_volatile_java_5.shtml
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