Part 3 · 1 chapters · ~8 min

Lock-Free Basics

Atomic operations and compare-and-swap, a lock-free counter and stack, the ABA problem, progress guarantees (lock-free, wait-free, obstruction-free), why lock-free is not automatically faster (contention, measured in Computers part 8), and when to use the libraries instead.

6

Compare-and-swap

code
// compare-and-swap loop: retry until no one else changed the value in between
// (Go)
for {
    old := atomic.LoadInt64(&balance)
    if old < amount { return ErrInsufficient }
    if atomic.CompareAndSwapInt64(&balance, old, old-amount) { return nil }   // succeeded atomically
    // someone else changed it: loop and try again with the new value
}

// Java: AtomicLong.updateAndGet, LongAdder for heavily contended counters (stripes internally)
LongAdder requests = new LongAdder(); requests.increment(); long total = requests.sum();
conceptmeaning
lock-freesome thread always makes progress, even if others are paused
wait-freeevery thread finishes in a bounded number of steps
ABA problema value changes A → B → A between your read and your CAS, so CAS succeeds wrongly; fix with version counters or hazard pointers
contentionmany threads CASing one location retry constantly; striping (LongAdder) or sharding helps

Lock-free structures are hard to write correctly. Use the ones your platform provides (Java's java.util.concurrent, Go's sync/atomic and channels, Rust's crossbeam) and keep shared state small.