Synchronization

Overview

The sync package provides low-level synchronization primitives for coordinating goroutines.

sync.Mutex

var (
    mu    sync.Mutex
    count int
)

func increment() {
    mu.Lock()
    count++
    mu.Unlock()
}

// With defer
func safe() {
    mu.Lock()
    defer mu.Unlock()
    // Critical section
}

sync.RWMutex

var (
    mu   sync.RWMutex
    data map[string]string
)

func read(key string) string {
    mu.RLock()
    defer mu.RUnlock()
    return data[key]
}

func write(key, value string) {
    mu.Lock()
    defer mu.Unlock()
    data[key] = value
}

sync.WaitGroup

var wg sync.WaitGroup

for i := 0; i < 5; i++ {
    wg.Add(1)
    go func(n int) {
        defer wg.Done()
        work(n)
    }(i)
}

wg.Wait()

sync.Once

var (
    once   sync.Once
    config *Config
)

func getConfig() *Config {
    once.Do(func() {
        config = loadConfig()  // Runs exactly once
    })
    return config
}

sync.Pool

var pool = sync.Pool{
    New: func() any {
        return make([]byte, 1024)
    },
}

func process() {
    buf := pool.Get().([]byte)
    defer pool.Put(buf)
    // Use buf
}

sync.Map

var m sync.Map

m.Store("key", "value")
v, ok := m.Load("key")
m.Delete("key")
m.Range(func(k, v any) bool {
    fmt.Println(k, v)
    return true  // Continue iteration
})

atomic Package

import "sync/atomic"

var counter int64

atomic.AddInt64(&counter, 1)
value := atomic.LoadInt64(&counter)
atomic.StoreInt64(&counter, 0)

Summary

Type Purpose
Mutex Exclusive lock
RWMutex Reader/writer lock
WaitGroup Wait for goroutines
Once Single execution
Pool Object reuse
Map Concurrent map