References:
[1]. http://www.javaworld.com/article/2074481/java-concurrency/java-101--understanding-java-threads--part-4---thread-groups--volatility--and-threa.html?page=2
1. Volatility
Volatility, that is, changeability, describes the situation where one thread changes a shared field variable‘s value and another thread sees that change. You expect other threads to always see a shared field variable‘s value, but that is not necessarily the case. For performance reasons, Java does not require a JVM implementation to read a value from or write a value to a shared field variable in main memory, or object heap memory. Instead, the JVM might read a shared field variable‘s value from a processor register or cache, collectively known as working memory. Similarly, the JVM might write a shared field variable‘s value to a processor register or cache. That capability affects how threads share field variables, as you will see.
Suppose a program creates a shared integer-field variable x
whose initial value in main memory is 10. This program starts two threads; one thread writes to x
, and the other reads x
‘s value. Finally, this program runs on a JVM implementation that assigns each thread its own private working memory, meaning each thread has its own private copy of x
. When the writing thread writes 6 to x
, the writing thread only updates its private working-memory copy of x
; the thread does not update the main-memory copy. Also, when the reading thread reads from x
, the returned value comes from the reading thread‘s private copy. Hence, the reading thread returns 10 (because a shared field variable‘s private working-memory copies initialize to values taken from the main-memory counterpart), not 6. As a result, one thread is unaware of another‘s change to a shared field variable.
The volatile
keyword ensures that when a thread writes to a volatile shared field variable, the JVM modifies the main-memory copy, not the thread‘s working-memory copy. Similarly, the JVM ensures that a thread always reads from the main-memory copy.
The visibility problem does not occur when threads use synchronization to access shared field variables. When a thread acquires a lock, the thread‘s working-memory copies of shared field variables reload from their main-memory counterparts. Similarly, when a thread releases a lock, the working-memory copies flush back to the main-memory shared field variables.
New developers sometimes think volatility replaces synchronization. Although volatility, through keywordvolatile
, lets you assign values to long-integer or double-precision floating-point shared field variables outside a synchronized context, volatility cannot replace synchronization. Synchronization lets you group several operations into an indivisible unit, which you cannot do with volatility. However, because volatility is faster than synchronization, use volatility in situations where multiple threads must communicate via a single shared field variable.