patterngoModerate
sync.Mutex vs sync.RWMutex: choose based on read/write ratio
Viewed 0 times
sync.Mutexsync.RWMutexread lockwrite lockconcurrencyread heavymutex performance
Problem
Using sync.Mutex for a data structure that is read far more often than written serialises all readers unnecessarily, reducing throughput.
Solution
Use sync.RWMutex when reads dominate. Lock() for writes, RLock() for reads:
type SafeCache struct {
mu sync.RWMutex
store map[string]string
}
func (c *SafeCache) Get(key string) (string, bool) {
c.mu.RLock()
defer c.mu.RUnlock()
v, ok := c.store[key]
return v, ok
}
func (c *SafeCache) Set(key, value string) {
c.mu.Lock()
defer c.mu.Unlock()
c.store[key] = value
}Why
RWMutex allows multiple concurrent readers. A plain Mutex lets only one goroutine in at a time regardless of whether it reads or writes. For read-heavy workloads, this is a significant throughput bottleneck.
Gotchas
- RWMutex has higher overhead than Mutex — for highly contended write-heavy workloads, plain Mutex can be faster
- Upgrading an RLock to a Lock (while holding RLock) will deadlock — release RLock first
- Never copy a Mutex or RWMutex after first use — always embed by value in a struct and pass pointer to the struct
Revisions (0)
No revisions yet.