Volatile is used when you want to share a variable between multiple
threads. a) What is the difference bwteen declaring a (shared between
threads) variable volatile and not to ? b) Should we always declare it
volatile in we're accessing it from different threads? c) Does it make
sense to synchronize a volatile variable?
To understand volatile
, it is useful to think about the architectures of modern computer system hardware.
In order to accelerate performance, EACH PROCESSOR OR CORE has it's own local memory cache. Data that is present in this cache is local to the particular processor and is not visible to other processors. In addition, there can be data caches at almost any level up to and including the JVM itself.
When you think of threads in this way, i.e. a unit of execution that can be divided up among processors, it is easy to understand a very important fact of the Java Memory Model:
There is no guarantee that changes to a shared variable made in one thread will become visible to other threads that access the same variable (without synchronization).
Again, imagine that the data that has updated the shared variable is still located in a local processor cache that is not available to the other cores (and, so, therefore not available to the other threads executing on them).
The volatile
keyword provides you with a way of guaranteeing that changes to shared variables get written out to memory right away so that the changes that occur to them are visible to other threads. Volatile
is useful in simple situations, and while it provides improved liveness to data, it provides no guarantees of atomicity and so it can provide no guarantees that race conditions on the shared variable still won't occur.
If mutating an object from one logical state to another requires multiple steps, then synchronizing the access to the object's state becomes necessary to preserve atomicity (either the update happens completely or not at all) even if the state transition involves only variables declared volatile
.