Concurrency Fundamentals • AtomicityMedium⏱️ ~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);
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);
AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet(); // returns new value
counter.getAndIncrement(); // returns old value
counter.compareAndSet(expected, newValue);
Atomics vs Mutexes Decision
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 { ... }