3. RW Mutex
The standard library also exposes a sync.RWMutex
In addition to these methods:
The sync.RWMutex also has these methods for concurrent reads:
The sync.RWMutex improves performance in read-intensive processes. Multiple goroutines can safely read from the map simultaneously, as many RLock() calls can occur at the same time. However, only one goroutine can hold a Lock(), and during this time, all RLock() operations are blocked.
The Problem with Regular Mutex
With sync.Mutex, ALL operations block each other, even if they're just reading:
// Using sync.Mutex
mu.Lock()
x := data["key"] // Just reading
mu.Unlock()
mu.Lock()
y := data["key"] // Also just reading, but has to wait!
mu.Unlock()Even though both are just reading (not changing anything), they block each other β this is wasteful.
The Solution: RWMutex (Read-Write Mutex)
sync.RWMutex has two types of locks:
How RWMutex Works
Scenario 1: Multiple Readers (No Writers)
All three can read simultaneously because reading doesn't change the data.
Scenario 2: Writer Arrives
Visual Comparison
sync.Mutex (Regular)
sync.RWMutex (Read-Write)
Code Example
When to Use Each
Use
sync.Mutexwhen:You have equal amounts of reads and writes
The code is simpler and you don't need optimization
You're mostly writing
Use
sync.RWMutexwhen:You have way more reads than writes (e.g., 90% reads, 10% writes)
Multiple goroutines need to read at the same time
Performance matters
Performance Difference
Example: 100 goroutines, 95 reading, 5 writing
With sync.Mutex:
With sync.RWMutex:
RWMutex can be 10x faster for read-heavy workloads!
Important Rules
Don't mix lock types:
Writers block everything:
RLock doesn't block other RLocks:
Can't upgrade locks:
Mental Model
Think of it like a library:
Regular Mutex (sync.Mutex):
Only ONE person allowed in the library at a time
Even if you just want to read, you have to wait for everyone else
RWMutex (sync.RWMutex):
Multiple readers can be in the library at once (using
RLock())ONE writer can be in the library alone (using
Lock())When a writer enters, all readers must leave and wait
When writer is done, readers can return
Summary
Readers
Block each other
Can run simultaneously
Writers
Block everyone
Block everyone
Best for
Equal R/W or mostly writes
Read-heavy workloads
Performance
Simpler, slower for reads
Faster for many reads
Methods
Lock(), Unlock()
Lock(), Unlock(), RLock(), RUnlock()
Key takeaway: Use RWMutex when you have lots of reads and few writes. It lets multiple goroutines read at the same time, making your code faster!
Assignment
Update the val method to only lock the mutex for reading. The test suite currently hangs because val locks the RWMutex with a write lock instead of a read lock.
Original (problematic) code:
Change the val method to use a read lock:
Run the test suite again β it should no longer hang once val uses RLock()/RUnlock().