Provides basic synchronization primitives for concurrent programs. While Go encourages communication via channels ("Do not communicate by sharing memory; share memory by communicating"), sync provides mutexes, wait groups, and once-only initialization for cases where shared state is necessary.
Import: import "sync" | Docs: pkg.go.dev/sync
| Name | Signature / Value | Description |
|---|---|---|
| sync.Mutex | type Mutex struct{} | Mutual exclusion lock |
| m.Lock | func (m *Mutex) Lock() | Lock the mutex (blocks until available) |
| m.Unlock | func (m *Mutex) Unlock() | Unlock the mutex |
| m.TryLock | func (m *Mutex) TryLock() bool | Non-blocking lock attempt (Go 1.18+) |
| sync.RWMutex | type RWMutex struct{} | Reader/writer mutual exclusion lock |
| rw.RLock/RUnlock | func (rw *RWMutex) RLock() | Acquire/release shared read lock |
| rw.Lock/Unlock | func (rw *RWMutex) Lock() | Acquire/release exclusive write lock |
| sync.WaitGroup | type WaitGroup struct{} | Wait for a collection of goroutines to finish |
| wg.Add | func (wg *WaitGroup) Add(delta int) | Add delta to WaitGroup counter |
| wg.Done | func (wg *WaitGroup) Done() | Decrement WaitGroup counter by 1 |
| wg.Wait | func (wg *WaitGroup) Wait() | Block until counter reaches 0 |
| sync.Once | type Once struct{} | Execute a function exactly once |
| once.Do | func (o *Once) Do(f func()) | Call f the first time Do is called |
| sync.Map | type Map struct{} | Concurrent map safe for goroutines |
| m.Store | func (m *Map) Store(key, value any) | Set key to value |
| m.Load | func (m *Map) Load(key any) (value any, ok bool) | Get value for key |
| m.Delete | func (m *Map) Delete(key any) | Delete a key |
| m.Range | func (m *Map) Range(f func(key, value any) bool) | Iterate over all key-value pairs |
| sync.Pool | type Pool struct{ New func() any } | Pool of reusable objects (reduces GC pressure) |
| pool.Get/Put | func (p *Pool) Get() any | Get/return an object from the pool |
Save as main.go inside any directory and run with go run main.go. No extra packages to install — all standard library.
package main
import (
"fmt"
"sync"
"time"
)
// Safe counter using Mutex
type SafeCounter struct {
mu sync.Mutex
count int
}
func (c *SafeCounter) Inc() {
c.mu.Lock()
defer c.mu.Unlock()
c.count++
}
func (c *SafeCounter) Value() int {
c.mu.Lock()
defer c.mu.Unlock()
return c.count
}
// Once: initialize exactly once
var (
instance string
once sync.Once
)
func getInstance() string {
once.Do(func() {
fmt.Println(" [initializing singleton...]")
instance = "MyWebUniversity-Config-v1"
})
return instance
}
func main() {
// --- WaitGroup ---
var wg sync.WaitGroup
counter := &SafeCounter{}
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
counter.Inc()
time.Sleep(time.Millisecond)
}()
}
wg.Wait()
fmt.Println("Final counter:", counter.Value())
// --- sync.Once ---
for i := 0; i < 3; i++ {
fmt.Println("Instance:", getInstance())
}
// --- sync.Map ---
var sm sync.Map
sm.Store("language", "Go")
sm.Store("version", "1.22")
sm.Store("creator", "Google")
sm.Range(func(k, v any) bool {
fmt.Printf(" %s = %s\n", k, v)
return true
})
val, ok := sm.Load("language")
fmt.Printf("Load: language=%v ok=%v\n", val, ok)
}
// go run main.go← net/http | 🏠 Index | bufio →