Sobes.tech
Middle

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();
    }
}