A condition variable coordinates goroutines waiting for an event. A listener waits while a shared condition is false; an updater broadcasts after changing the shared state. section 9.12
Avoid treating notification as the condition itself:
- Check the condition in a loop, not just once, because Wait only suspends execution until notification. section 9.12
- Call Wait while holding the condition's Locker; it unlocks during suspension and relocks before returning. section 9.12
- Broadcast after updating shared state, and protect that state with the same mutex to prevent races. section 9.12
Donation goals
Two listener goroutines wait for one shared donation balance to reach different goals. The updater increments the balance and broadcasts each update, allowing each listener to finish at its own threshold. section 9.12
type Donation struct {
cond *sync.Cond #1
balance int
}
donation := &Donation{
cond: sync.NewCond(&sync.Mutex{}), #2
}
// Listener goroutines
f := func(goal int) {
donation.cond.L.Lock()
for donation.balance < goal {
donation.cond.Wait() #3
}
fmt.Printf("%d$ goal reached\n", donation.balance)
donation.cond.L.Unlock()
}
go f(10)
go f(15)
// Updater goroutine
for {
time.Sleep(time.Second)
donation.cond.L.Lock()
donation.balance++ #4
donation.cond.L.Unlock()
donation.cond.Broadcast() #5
}
Inspect the complete sync.Cond arrangement, including the mutex, listener loop, Wait call, updater, and Broadcast. section 9.12






