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*.