3. RW Mutex

The standard library also exposes a sync.RWMutexarrow-up-right

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:

1

Read Lock (RLock)

  • Multiple goroutines can hold this at the same time.

  • Use for reading-only operations.

2

Write Lock (Lock)

  • Only ONE goroutine can hold this.

  • Blocks all other readers and writers while held.

  • Use for mutating operations.

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.Mutex when:

    • You have equal amounts of reads and writes

    • The code is simpler and you don't need optimization

    • You're mostly writing

  • Use sync.RWMutex when:

    • 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

circle-exclamation

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

Feature
sync.Mutex
sync.RWMutex

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().