index
In the previous example we saw how to manage simple counter state using [atomic operations](atomic-counters). For more complex state we can use a <em>[mutex](http://en.wikipedia.org/wiki/Mutual_exclusion)</em> to safely access data across multiple goroutines.
package main
import (
	"fmt"
	"math/rand"
	"sync"
	"sync/atomic"
	"time"
)
func main() {
For our example the `state` will be a map.
	var state = make(map[int]int)
This `mutex` will synchronize access to `state`.
	var mutex = &sync.Mutex{}
We'll keep track of how many read and write operations we do.
	var readOps uint64
	var writeOps uint64
Here we start 100 goroutines to execute repeated reads against the state, once per millisecond in each goroutine.
	for r := 0; r < 100; r++ {
		go func() {
			total := 0
			for {
For each read we pick a key to access, `Lock()` the `mutex` to ensure exclusive access to the `state`, read the value at the chosen key, `Unlock()` the mutex, and increment the `readOps` count.
				key := rand.Intn(5)
				mutex.Lock()
				total += state[key]
				mutex.Unlock()
				atomic.AddUint64(&readOps, 1)
Wait a bit between reads.
				time.Sleep(time.Millisecond)
			}
		}()
	}
We'll also start 10 goroutines to simulate writes, using the same pattern we did for reads.
	for w := 0; w < 10; w++ {
		go func() {
			for {
				key := rand.Intn(5)
				val := rand.Intn(100)
				mutex.Lock()
				state[key] = val
				mutex.Unlock()
				atomic.AddUint64(&writeOps, 1)
				time.Sleep(time.Millisecond)
			}
		}()
	}
Let the 10 goroutines work on the `state` and `mutex` for a second.
	time.Sleep(time.Second)
Take and report final operation counts.
	readOpsFinal := atomic.LoadUint64(&readOps)
	fmt.Println("readOps:", readOpsFinal)
readOps: 90600
	writeOpsFinal := atomic.LoadUint64(&writeOps)
	fmt.Println("writeOps:", writeOpsFinal)
readOps: 90200
writeOps: 9020
With a final lock of `state`, show how it ended up.
	mutex.Lock()
readOps: 90200
writeOps: 9020
	fmt.Println("state:", state)
readOps: 90496
writeOps: 9060
state: map[0:28 1:96 2:48 3:35 4:62]
	mutex.Unlock()
readOps: 90339
writeOps: 9032
state: map[0:53 1:75 2:91 3:37 4:59]
}
readOps: 91400
writeOps: 9140
state: map[0:48 1:61 2:77 3:54 4:43]
index