Atomics vs Mutexes
Simple guideline
Start with mutexes (clearer, safer). Only switch to atomics if profiling shows a performance bottleneck and the shared state is simple enough.
Atomics
Atomics (from sync/atomic) provide low-level, lock-free, single-variable operations.
-
What they do:
- Read, write, and modify integers, pointers, and unsafe.Pointer atomically.
- Examples: atomic.AddInt64, atomic.LoadPointer, atomic.CompareAndSwapInt32.
-
When to use:
-
Protecting a single counter/flag/state variable.
var counter int64
atomic.AddInt64(&counter, 1) -
Implementing lock-free algorithms.
-
Fast-path optimizations where contention is low.
-
Performance-critical code where avoiding the overhead of a mutex matters.
-
-
Advantages:
- Very fast (no kernel call, no blocking).
- Scales well under high contention if operations are simple.
-
Disadvantages:
- Limited to simple operations (no complex invariants).
- Easy to misuse → subtle bugs, memory-ordering issues.
- Code harder to read/maintain.
Mutexes
Mutexes (sync.Mutex, sync.RWMutex) provide higher-level mutual exclusion.
-
What they do:
- Lock a critical section so only one goroutine can enter at a time.
- RWMutex allows multiple readers, but only one writer.
-
When to use:
-
Protecting compound state (structs, maps, slices).
var mu sync.Mutex
m := make(map[string]int)
mu.Lock()
m["a"]++
mu.Unlock()- When multiple variables need to be updated consistently (atomic can’t ensure invariants).
- When correctness and clarity are more important than raw performance.
-
-
Advantages:
- Easy to reason about.
- Works for complex invariants, multiple fields.
- Safer and clearer than atomics in most cases.
-
Disadvantages:
- Slower than atomics (involves locking/unlocking).
- Can cause contention and blocking.
- Deadlocks possible if misused.
Summary
- Use atomics for:
- Simple counters, flags, or single shared integers/pointers.
- Performance-critical hot paths.
- Use mutexes for:
- Protecting composite data structures.
- Ensuring consistency across multiple variables.
- Most cases where correctness matters more than raw speed.