Java.Multithreading.What is the difference between volatile and Atomic variables?

volatile and atomic variables often seem similar at first glance, but they serve different purposes and offer different guarantees in Java concurrency.

🧠 Short Answer:

FeaturevolatileAtomic variables (AtomicInteger, etc.)
GuaranteesVisibility onlyVisibility + Atomicity
Atomic operations?❌ No✅ Yes
Use for increment?❌ Not safe✅ Safe (e.g., incrementAndGet())
Use caseFlags, simple single-writer variablesCounters, accumulators, CAS-style logic
Thread-safe updates❌ No✅ Yes

📘 volatile — Visibility Guarantee

Declaring a variable volatile ensures that:

  • All threads always see the latest value.
  • Writes go directly to main memory, and reads always come from main memory.

BUT:

volatile does not make operations atomic — e.g., ++x is not thread-safe!

Example — ❌ Broken counter with volatile

volatile int count = 0;

public void increment() {
    count++; // Not atomic: read-modify-write
}

Multiple threads calling increment() can lead to lost updates.

🔐 Atomic Variables (e.g., AtomicInteger)

These are part of java.util.concurrent.atomic and provide:

  • Atomic read-modify-write operations
  • Internally use low-level CAS (Compare-And-Swap) operations
  • Extremely efficient and lock-free

Example — ✅ Safe counter with AtomicInteger

AtomicInteger count = new AtomicInteger(0);

public void increment() {
    count.incrementAndGet(); // atomic
}

This is thread-safe and lock-free.

🔍 Why Atomic* Is Better for Shared Counters

Let’s say 3 threads try to increment a counter:

  • With volatile, one might read 5, increment to 6, and write 6, even though others have already made it 7 or 8.
  • With AtomicInteger, it’ll internally retry using CAS until the increment is successful.

📦 When to Use What?

Use CaseBest Tool
Stop signal or flagvolatile
Status monitoring (no increments)volatile
Shared counter, sequence numberAtomicInteger
Lock-free algorithmsAtomic* types
Compound operations (x += y)Atomic* or synchronized

🧠 Summary

  • volatile: Great for simple flags and ensuring visibility.
  • Atomic variables: Best for safe concurrent updates to counters or shared data.
  • If you need atomicity, use Atomic* or synchronized.
This entry was posted in Без рубрики. Bookmark the permalink.