liveBook · Manning

Atomicity

As explained in 100 Go Mistakes and How to Avoid Them

An atomic operation is an indivisible operation that cannot be interrupted by competing accesses to the same data.

Atomicity makes an operation indivisible: competing goroutines cannot interleave its accesses and lose an update. A plain i++ can read, increment, and write separately, producing 1 instead of 2. section 8.4.1

var i int64
 
go func() {
    atomic.AddInt64(&i, 1)    #1
}()
 
go func() {
    atomic.AddInt64(&i, 1)    #2
}()

Use sync/atomic to increment an int64 as one operation, regardless of goroutine execution order. section 8.4.1

Choose the synchronization boundary that matches the data:

  • Use sync/atomic for supported numeric types such as int64. section 8.4.1
  • Use a mutex when the critical section involves slices, maps, structs, or other unsupported data. section 8.4.1
  • Use a channel when goroutines can communicate increments instead of sharing the same memory location. section 8.4.1

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Explains interleaved increments, demonstrates sync/atomic, and contrasts mutexes and channels; it omits atomic.Value.
Examples
Uses competing i++ operations, an atomic int64 increment, a mutex-protected increment, and channel-based increment notifications.
What it assumes
Assumes goroutines and shared variables, then explains data-race interleavings before introducing synchronization choices.
What you can do after
Apply it via sync/atomic to make supported numeric updates deterministic across goroutines.
How it connects
Connects atomic operations with data races, goroutines, mutexes, critical sections, and channels.

Also explained in

Compare how 13 books explain atomicity →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.