HowtoGo
Home / Standard Library / The sync Package
Standard Library

The sync Package

sync provides basic synchronization primitives: mutexes, wait groups, one-time initialization, condition variables, and two specialized concurrent-safe containers.

A sync.Mutex protects the shared counter and a sync.WaitGroup tracks the 100 goroutines writing to it.

var (
    mu      sync.Mutex
    wg      sync.WaitGroup
    counter int
)

for i := 0; i < 100; i++ {
    wg.Add(1)
    go func() {
        defer wg.Done()
        mu.Lock()
        counter++
        mu.Unlock()
    }()
}

wg.Wait()
fmt.Println(counter)

Every increment is serialized by the lock, so the final count is exact regardless of goroutine scheduling.

Terminal
$ go run main.go
100

Mutex

FunctionDescription
Lock()
mu.Lock()
Blocks until the lock is free, then acquires it
Unlock()
mu.Unlock()
Releases the lock; panics if the mutex isn't currently locked
TryLock() bool
ok := mu.TryLock()
Acquires the lock without blocking, reporting whether it succeeded

RWMutex

FunctionDescription
Lock() / Unlock()
mu.Lock()
Exclusive write lock; blocks every other reader and writer
RLock() / RUnlock()
mu.RLock()
Shared read lock; any number of readers can hold it at once
TryLock() bool
ok := mu.TryLock()
Acquires the write lock without blocking
TryRLock() bool
ok := mu.TryRLock()
Acquires a read lock without blocking

WaitGroup

FunctionDescription
Add(delta int)
wg.Add(1)
Adds delta to the counter; delta may be negative
Done()
defer wg.Done()
Decrements the counter by one, shorthand for Add(-1)
Wait()
wg.Wait()
Blocks until the counter returns to zero

Once

FunctionDescription
Do(f func())
once.Do(setup)
Runs f exactly once, no matter how many goroutines call Do concurrently

Cond

FunctionDescription
NewCond(l Locker) *Cond
c := sync.NewCond(&mu)
Creates a Cond backed by an existing Locker, usually a *Mutex
Wait()
c.Wait()
Unlocks the Locker, suspends the goroutine, and relocks before returning
Signal()
c.Signal()
Wakes one goroutine waiting on the condition, if any are waiting
Broadcast()
c.Broadcast()
Wakes every goroutine waiting on the condition

Map

FunctionDescription
Load(key any) (value any, ok bool)
v, ok := m.Load("id")
Reads the value stored for key
Store(key, value any)
m.Store("id", 1)
Sets the value for key
Delete(key any)
m.Delete("id")
Removes the value stored for key
LoadOrStore(key, value any) (actual any, loaded bool)
v, loaded := m.LoadOrStore("id", 1)
Returns the existing value if present, otherwise stores and returns value
LoadAndDelete(key any) (value any, loaded bool)
v, ok := m.LoadAndDelete("id")
Removes key and returns the value that was stored
Swap(key, value any) (previous any, loaded bool)
old, loaded := m.Swap("id", 2)
Stores value and returns the value it replaced
CompareAndSwap(key, old, new any) bool
m.CompareAndSwap("id", 1, 2)
Swaps only if the stored value equals old
CompareAndDelete(key, old any) bool
m.CompareAndDelete("id", 2)
Deletes only if the stored value equals old
Range(f func(key, value any) bool)
m.Range(func(k, v any) bool { return true })
Calls f for each entry until f returns false; iteration order isn't guaranteed

Pool

FunctionDescription
New func() any
p := sync.Pool{New: func() any { return new(bytes.Buffer) }}
Factory field called to create a value whenever Get finds the pool empty
Get() any
buf := p.Get().(*bytes.Buffer)
Removes and returns an item from the pool, or calls New if the pool is empty
Put(x any)
p.Put(buf)
Adds x back to the pool for a later Get to reuse