Java
provides weaker form of synchronization called ‘volatile variable’ to ensure
any update to variable is propagated to all other threads. Locking guarantees
both visibility and atomicity but volatile only guarantees visibility.
The
Visibility effect of volatile variables extends beyond the value of the
volatile variable itself. When thread A writes to a volatile variable and
subsequently thread B reads that same variable, the values of all variables
that were visible to A prior to writing to volatile variable become visible to
B after reading the volatile variable. So writing to a volatile variable works
like entering into a synchronized block. However its not recommended to rely on
volatile variables too heavily for visibility as it makes code more fragile and
hard to understand.
Volatile
variables are not thread safe for 64 bit operations as they are Non-atomic.
Using volatile for 32 bit operations are fine but when you use it with 64 bit
numeric variables, like double and long, JVM is permitted to divide 62 bit read
or write operation into two 32 bit read or write operation. If read and writes
are happening in two different threads its possible reader might read 32 bit
updated value and 32 bit old value and overall unexpected dirty value as volatile
doesn't guarantee atomicity.
For atomic read-modify-write support Java
provide 9 different flavors of Atomic Variables/References which can be used
to overcome above problem.