What is volatile keyword in Java

Upasana | May 01, 2019 | 3 min read | 350 views | algorithm-datastructures


Volatile Keyword in Java

Volatile keyword in Java is used in multi-threaded environment to ensure that updates to a given variable are propagated to other threads in a deterministic manner. Thus it is a weaker form of synchronization where Java Memory Model ensures visibility guarantee for any volatile variable.

Java Memory Model ensures that
  1. Changes to volatile variables are not cached in registers or other cache where they are hidden from other threads. Instead read and write to volatile variable always flushes the changes to main memory, thus any thread can read the most recent write by any other thread.

  2. Compiler and runtime do not reorder the operations with other memory operations for volatile variables (aka no optimzation will be done). This ensures happen before relationship.

  3. Reads and writes are atomic for all variables that are declared volatile. This includes long and double variables too (irrespective the architecture of the OS x64 or 32 bit).

  4. If Thread A writes to a volatile variable and Thread B subsequently reads the same volatile variable, then all variables visible to Thread A before writing the volatile variable, will also be visible to Thread B after it has read the volatile variable. This is very important feature of volatile variables.

What is difference between synchronization and volatile variable?

volatile variable only guarantees visibility guarantee while synchronization offers visibility and locking capabilities. So if we want to ensure that no two threads change the state of object at same time, then volatile has very little to offer.

Must Remember

Locking can guarantee both visibility and atomicity; volatile variables can only guarantee visibility. Locking can be achieved by use of synchronized keyword in Java.

When to use volatile instead of synchronization?

According to Brian Goetz in his book "Concurrency in Practice, 2006 Edition", you can use volatile variables only when all the following criteria are met:

  1. Writes to the variable do not depend on its current value, or you can ensure that only a single thread ever updates the value;

  2. The variable does not participate in invariants with other state variables and

  3. Locking is not required for any other reason while the variable is being accessed.

Usecase for volatile Keyword

A typical usecase for volatile keyword can be that of checking the state of variable inside a while loop.

volatile boolean asleep;
...
while (!asleep) {
  doSomeWork();
}
//Other thread can make changes to asleep variable.

Bad Usecase for volatile keyword

Scenarios that require "Check then Act" can not be implemented using volatile keyword because they require locking to ensure that no other thread changes state in between check and the act operation. volatile keywords can not be used to implement a thread-safe counter. For example, below is a bad usecase for volatile because volatile variable can not guarantee locking.

Never do this in multi-thread environment
volatile int counter;

public int increment(){
  return counter++;      (1)
}
1 two threads can risk memory consistency errors since volatile keyword does not guarantee locking. This code is prone to RACE conditions.

The above code will fail in multi-threaded environment. Right candidate for such scenario is AtomicInteger which uses CAS for non-blocking locking and volatile for memory visibility.

That’s All.


Top articles in this category:
  1. What is AtomicInteger class and how it works internally
  2. What is Double Checked Locking Problem in Multi-Threading?
  3. what are Key classes in java.util.concurrent package
  4. What is difference between sleep() and wait() method in Java?
  5. What is purpose of Collections.unmodifiableCollection
  6. Troubleshooting Deadlock in Java
  7. What is Immutable Class in Java

Recommended books for interview preparation:

Find more on this topic: