Concurrency FundamentalsAtomicityMedium⏱️ ~2 min

Atomic Variables in Practice

Key Insight
Languages provide atomic types that wrap hardware primitives. They guarantee both atomicity and proper memory ordering.

Common Operations

// C++
std::atomic<int> counter{0};
counter.fetch_add(1); // atomic increment
counter.load(); // atomic read
counter.store(5); // atomic write
counter.compare_exchange_strong(expected, desired);

Java AtomicInteger

// Java
AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet(); // returns new value
counter.getAndIncrement(); // returns old value
counter.compareAndSet(expected, newValue);
Atomics vs Mutexes Decision
USE ATOMICSSingle variable updatesCounters, flags, pointersLock-free performance criticalUSE MUTEXMultiple variable invariantsComplex update logicReadability over performance

When To Use Atomics

Counters: Statistics, metrics, reference counts. Simple increment/decrement.

Flags: Boolean signals like shutdown requested or initialization complete.

Lock-free algorithms: Building queues, stacks without mutexes. Advanced territory.

When Not To Use Atomics

Complex invariants: If multiple variables must be updated together, atomics are not enough. Use a mutex.

Conditional updates: If the update logic is complex, the CAS loop becomes unreadable. A mutex is clearer.

Warning: Atomics are not automatically better than mutexes. They are a different tool for different problems.
💡 Key Takeaways
Java provides AtomicInteger, AtomicLong, AtomicReference in java.util.concurrent.atomic package.
C++ provides std::atomic<T> template. Use atomic<int>, atomic<bool>, atomic<shared_ptr<T>>.
Go provides sync/atomic package with AddInt64, LoadInt64, StoreInt64, CompareAndSwapInt64.
Atomics are faster than locks: no context switch, no blocking. Use for simple single variable operations.
Multiple atomic operations are NOT atomic together. Two atomic reads can see inconsistent state between them.
📌 Examples
1Java atomic counter: AtomicInteger counter = new AtomicInteger(0); counter.incrementAndGet();
2Go atomic flag: var done int32; atomic.StoreInt32(&done, 1); if atomic.LoadInt32(&done) == 1 { ... }
← Back to Atomicity Overview