Concurrency Fundamentals • AtomicityHard⏱️ ~3 min
Atomicity Limitations and Trade offs
Key Insight
Atomicity solves one problem but creates others. Understanding the trade-offs helps you choose the right synchronization approach.
Atomics vs Mutexes Trade-offs
The ABA Problem
CAS checks if value equals expected and swaps. But what if value was A, changed to B, then back to A? CAS succeeds even though the value changed. This breaks algorithms that assume unchanged means untouched.
Memory Ordering Complexity
Atomics with relaxed ordering are faster but have subtle semantics. Sequential consistency is safer but slower. Most developers should use the defaults (seq_cst in C++, volatile in Java).
Starvation Under Contention
CAS loops retry on failure. Under high contention, a thread might retry thousands of times while others succeed. Mutexes have fairer queuing.
Rule of Thumb: Use atomics for simple counters/flags. Use mutexes for anything involving multiple variables or complex logic.
💡 Key Takeaways
✓Atomics work on single memory locations. Multiple related variables still need locks for consistency.
✓ABA problem: CAS cannot detect if value changed and changed back. Fix with version counters or hazard pointers.
✓High contention degrades atomic performance. CAS retry loops waste CPU. Locks let waiting threads sleep.
✓Lock free code is extremely difficult to write correctly. Use proven libraries rather than rolling your own.
✓Measure before optimizing. Locks are often fast enough. Atomics add complexity that may not pay off.
📌 Examples
1ABA in stack pop: Thread A pops node X (head is X.next). Thread B pops X and Y, pushes X back. A's CAS succeeds but Y is lost.
2Java AtomicStampedReference includes version stamp to detect ABA: compareAndSet(expectedRef, newRef, expectedStamp, newStamp).