Golang Concurrency #8 - Mutexes

Just a guy who loves to write code and watch anime.
Introduction
Mutexes solve the problem: "What happens when multiple goroutines access the same variable?"
The Problem: Race Condition
var counter int
func main() {
for i := 0; i < 1000; i++ {
go func() {
counter++ // Multiple goroutines modifying same variable
}()
}
time.Sleep(time.Second)
fmt.Println("Counter:", counter) // Should be 1000, but isn't!
}
Why it breaks
Goroutine 1: Read counter (0) → Add 1 → Write back (1)
Goroutine 2: Read counter (0) → Add 1 → Write back (1)
Both read 0 at the same time, both write 1. We lost an increment!
The Solution: Mutex (Mutual Exclusion)
var counter int
var mutex sync.Mutex
func main() {
for i := 0; i < 1000; i++ {
go func() {
mutex.Lock() // "I need exclusive access"
counter++ // Only one goroutine can do this at a time
mutex.Unlock() // "I'm done, others can proceed"
}()
}
time.Sleep(time.Second)
fmt.Println("Counter:", counter) // Now correctly prints 1000
}
How Mutex works
Lock()- "Wait until no one else is using this, then it's mine"Unlock()- "I'm done, next goroutine can have it"Only one goroutine can hold the lock at a time
Better pattern with defer
func increment() {
mutex.Lock()
defer mutex.Unlock() // Automatically unlock when function exits
counter++
// Even if panic happens, mutex gets unlocked
}
RWMutex (Read/Write Mutex)
var data map[string]int
var rwMutex sync.RWMutex
func readData(key string) int {
rwMutex.RLock() // Multiple readers allowed
defer rwMutex.RUnlock()
return data[key]
}
func writeData(key string, value int) {
rwMutex.Lock() // Exclusive write access
defer rwMutex.Unlock()
data[key] = value
}
When to use mutexes
Protecting shared variables (counters, maps, slices)
When you need to update data structures
When channels would be overkill
Remember
Always pair
Lock()withUnlock()Use
deferto ensure unlockingKeep critical sections (locked code) small and fast
Prefer channels when possible, use mutexes when necessary






