What is the difference between volatile and atomic variables?
sobes.tech AI
Answer from AI
volatile ensures visibility of variable changes across different threads and prevents the compiler and JVM from reordering instructions related to this variable. This guarantees that when reading a volatile variable, a thread will see the most recently written value. However, volatile does not guarantee atomicity of compound operations (e.g., increment).
Atomic classes from the java.util.concurrent.atomic package (such as AtomicInteger, AtomicLong, AtomicReference) use low-level atomic operations like Compare-And-Swap (CAS), which are performed at the hardware level. They guarantee that read-modify-write operations are atomic, without the need for explicit synchronization using synchronized.
Comparison:
| Feature | volatile |
Atomic variables (AtomicInteger, etc.) |
|---|---|---|
| Atomicity | Does not guarantee atomicity of compound operations. | Guarantee atomicity of operations (CAS). |
| Visibility | Guarantees visibility of changes to other threads. | Guarantee visibility (side effect of CAS). |
| Usage | For ensuring visibility of simple read/write. | For atomic operations like increment, CAS. |
| Overhead | Less overhead than synchronized. |
Usually less overhead than synchronized under low contention. |
Example of using volatile:
class SharedData {
volatile boolean flag = false; // Ensures visibility of flag changes
public void setFlag() {
flag = true;
}
public boolean isFlag() {
return flag;
}
}
Example of using AtomicInteger:
import java.util.concurrent.atomic.AtomicInteger;
class Counter {
AtomicInteger count = new AtomicInteger(0); // Atomic counter
public void increment() {
count.incrementAndGet(); // Atomic increment
}
public int getCount() {
return count.get();
}
}