volatile đảm bảo visibility giữa các thread — mọi read/write đi thẳng main memory, không qua CPU cache. Đây là keyword nhẹ nhất trong concurrency toolbox.
Không có volatile, JVM/CPU có thể cache biến → thread A đổi nhưng thread B vẫn thấy giá trị cũ. Loop dưới có thể chạy mãi:
boolean stop = false; // KHÔNG volatile
while (!stop) { /* work */ } // có thể vô hạn — JVM cache stop→ Thêm volatile boolean stop để fix.
volatile đảm bảo: visibility + happens-before + no reordering.
volatile KHÔNG đảm bảo atomicity:
volatile int count = 0;
count++; // ❌ vẫn race — đây là read-modify-write 3 bước
// Dùng AtomicInteger
AtomicInteger c = new AtomicInteger();
c.incrementAndGet(); // ✅ atomicUse case đúng:
- Boolean flag (volatile boolean shutdown).
- Singleton DCL — private static volatile Logger instance (bắt buộc).
- Reference immutable object — đổi reference, không sửa nội bộ.
- Write 1 thread, read nhiều thread.
So sánh:
volatile | synchronized | Atomic* | |
|---|---|---|---|
| Visibility | ✅ | ✅ | ✅ |
| Atomicity (compound op) | ❌ | ✅ | ✅ (op đơn giản) |
| Cost | Rẻ nhất | Đắt nhất | Rẻ (CAS) |
volatile không phải "synchronized rẻ". Compound op (++, check-then-act) phải dùng synchronized hoặc Atomic*.
volatile guarantees visibility across threads — reads/writes go straight to main memory, bypassing the CPU cache. It is the lightest keyword in the concurrency toolbox.
Without volatile, the JVM/CPU may cache a variable → thread A changes it but thread B still sees the old value. The loop below can run forever:
boolean stop = false; // NOT volatile
while (!stop) { /* work */ } // may loop forever — JVM caches stop→ Add volatile boolean stop to fix.
volatile provides: visibility + happens-before + no reordering.
volatile does NOT provide atomicity:
volatile int count = 0;
count++; // ❌ still races — read-modify-write
// Use AtomicInteger
AtomicInteger c = new AtomicInteger();
c.incrementAndGet(); // ✅ atomicProper use cases:
- Boolean flags (volatile boolean shutdown).
- Singleton DCL — private static volatile Logger instance (required).
- Reference to an immutable object — swap reference, never mutate.
- One writer, many readers.
Comparison:
volatile | synchronized | Atomic* | |
|---|---|---|---|
| Visibility | ✅ | ✅ | ✅ |
| Atomicity (compound) | ❌ | ✅ | ✅ (simple ops) |
| Cost | Cheapest | Most expensive | Cheap (CAS) |
volatile is not "cheap synchronized". Compound ops (++, check-then-act) need synchronized or Atomic*.