Java Volatile Keyword

Volatile is not always enough. Volatile is suitable solution only for reading and writing a value from/to variable. But imagine the situation when Thread 1 reads a shared counter variable with the value 0 into its CPU cache, increments it to 1 and does not write changed value back into main memory. Thread 2 could then read the same variable from main memory, where the value of the variable is still 0, into its own CPU cache. Thread 2 could then also increment the counter to 1 and also not write it back to main memory. This situation is illustrated in the diagram below :

Two threads have read a shared counter variable into their local CPU caches and incremented it.

Thread 1 and Thread 2 are now practically out of sync. The real value of the shared counter variable should have been 2, but each of the threads has the value 1 for the variable in its CPU cache, and in main memory the value is still 0. Even if threads eventually write their value for the shared counter variable back to main memory, the value will be wrong.

Besides, using volatile keyword does not imply object lock. So operations that require more than one line of byte code (non-atomic operations) can cause race condition – multiple threads might read the same value of the volatile variable, generate a new value for the variable and then overwrite each other’s values.

Performance Considerations of Volatile

Reading from and writing to main memory is more expensive than accessing the CPU cache. Accessing volatile variables also requires following certain reordering rules. Thus, volatile variables should be used only when developers need to enforce visibility of variables.


Leave a Reply

Your email address will not be published. Required fields are marked *