The <code>volatile</code> Keyword in Java
volatile guarantees that reads and writes of a field go to main memory, not a CPU register or cache. Writes are immediately visible to other threads; reads always fetch the latest value. It does not make compound operations (x++) atomic.
What volatile fixes
class Worker implements Runnable {
private boolean stopped; // β NOT volatile
public void run() {
while (!stopped) { doWork(); } // might loop forever β cached value
}
public void stop() { stopped = true; }
}
Without volatile, the JVM is free to cache stopped in a register inside run(). The stop flag set from another thread may never be seen.
private volatile boolean stopped; // β
every read sees the latest write
What volatile does not fix
private volatile int counter;
public void increment() {
counter++; // read + add + write β THREE operations
}
Two threads calling increment can interleave and lose updates. For atomicity, use AtomicInteger (or LongAdder for high-contention counters).
When to use it
- Stop/ready flags read by one thread, written by another.
- Publishing an immutable object reference after safe construction (double-checked locking idiom).
- Configuration that changes rarely and is read often.
Double-checked locking
private volatile Instance instance;
public Instance get() {
Instance local = instance;
if (local == null) {
synchronized (this) {
local = instance;
if (local == null) instance = local = new Instance();
}
}
return local;
}
The volatile is essential β without it, another thread could see a non-null reference pointing to a half-constructed Instance.
volatile vs synchronized vs Atomic*
| Visibility | Atomicity | Lock overhead | |
|---|---|---|---|
volatile | Yes | No (single read/write only) | Very low |
synchronized | Yes | Yes β whole critical section | Medium (lock acquisition) |
AtomicInteger | Yes | Yes β for single-word ops (CAS) | Low |
Common mistakes
- Expecting atomicity β
volatileonly helps visibility. For read-modify-write, useAtomicIntegeror a lock. - Using
volatileon a reference to a mutable object β the reference is visible, but the object's fields are still subject to races. - Using
volatileinstead ofsynchronizedfor protecting related fields β only individual reads/writes are synchronised, not groups.
Related
Pillar: Java keywords. See also synchronized.