A readers-writer lock protects shared data while permitting concurrency that a plain mutex would block. Any number of goroutines may hold the read side together, but a writer needs exclusive access: while writing, no other reader or writer may enter; while reading, writers wait. This makes the lock useful when updates are rare compared with reads, where serializing every lookup would unnecessarily limit throughput. section 4.0 section 4.2
In Go, `sync.RWMutex` separates the two kinds of critical section:
- Use `RLock()` before reading shared state and `RUnlock()` after the read-only work. Multiple readers can copy or inspect the same data concurrently. section 4.2.1
- Use `Lock()` before modifying shared state and `Unlock()` afterward. A write lock blocks every other access, like a normal mutex. section 4.2.1
- Choose it for read-heavy workloads rather than assuming it improves every concurrent program; ordinary mutexes remain appropriate when broad exclusion is needed. section 4.2 section 4.4
Serving frequent game-update requests
A server keeps match events in a shared slice. One recorder appends an event a few times per second, while thousands of client handlers repeatedly copy the event list. The recorder holds the write lock around `append`; each handler holds the read lock only while copying. Readers can run together, and observed runs finish substantially sooner than the version that gives every handler an exclusive mutex. section 4.2.1
Compare the two lock states: read access admits multiple goroutines but excludes writers, whereas write access excludes both readers and writers. section 4.2.1
A simple read-preferred implementation can be built from two ordinary mutexes and a reader counter. A reader briefly locks the counter, increments it, and the first reader locks a global mutex that writers require. On exit, a reader decrements the counter; the last reader releases that global mutex. This preserves concurrent reads while keeping writers out until all active readers leave. section 4.2.2
Read preference has a failure mode: a continuing stream of readers can leave no reader-free interval for a writer. This write starvation prevents an update indefinitely. A write-preferring design addresses it with a condition variable, tracking waiting writers and refusing new readers whenever a writer is waiting or active; readers and writers broadcast when their state changes. section 5.1.4 section 5.1.4
