A condition variable lets a goroutine stop until shared state may have changed. It complements a mutex: the mutex protects the state and the condition variable coordinates waiting, so a goroutine need not repeatedly unlock, sleep, and check again. Polling with arbitrary sleeps either wastes CPU time or delays work after the needed change has already happened. section 5.1 section 5.1.1
Use a condition variable around a predicate on shared state. Lock its associated mutex, check the predicate in a loop, and call Wait when the predicate is false. Wait atomically releases the mutex and suspends the goroutine; after Signal or Broadcast wakes it, Wait reacquires the mutex and the predicate is checked again. The loop matters because waking indicates that state may have changed, not that the condition is necessarily true. section 5.1.1 section 5.4
Follow the state transition: a waiting goroutine releases the mutex, an updating goroutine changes shared state and signals, then the waiter resumes and rechecks the condition. section 5.1.1
Wait until a balance can fund a withdrawal
A spending goroutine locks the condition variable’s mutex and waits while the account has less than 50. An earning goroutine locks the same mutex, adds funds, calls Signal, and unlocks. The spending goroutine resumes with the mutex held, rechecks the balance, and subtracts only when enough money is available. This prevents a negative balance without timed retrying. section 5.1.1
Choose the notification operation by the number of waiters that may proceed:
- Use Signal to resume one suspended goroutine. Which waiter resumes is arbitrary when several goroutines are waiting. section 5.1.3
- Use Broadcast to resume every goroutine suspended in Wait, then let each reacquire the mutex and evaluate its own condition. section 5.1.3
- Do not treat a notification as stored work: Signal or Broadcast is missed if no goroutine is waiting. section 5.1.2
Start a game after every player arrives
Each player handler decrements a shared remaining-player count while holding the mutex. Handlers wait while the count is above zero. The last player changes it to zero and calls Broadcast, allowing every waiting handler to continue into gameplay. This is a natural fit when one state transition releases a group. section 5.1.3
Condition variables can also define richer synchronization tools. A write-preferring readers–writer lock waits readers while writers are waiting or active, and waits writers while readers or another writer are active. Broadcasting when the last reader exits or a writer exits gives blocked goroutines another chance to test their conditions, avoiding writer starvation caused by continually arriving readers. section 5.1.4 section 5.4
They are building blocks rather than only application-level coordination. A waitgroup can protect a task count with a mutex, wait while the count remains positive, and broadcast when the final Done call reduces it to zero. The same approach can support more complete custom synchronization abstractions. section 6.1.4 section 1.5.3






