Go⚡Concurrencyintermediate
sync.Once
Go · Concurrency · Run with go run
Explanation
`sync.Once` guarantees a function runs exactly once, no matter how many goroutines call it or how often. The first call to `once.Do(f)` runs `f`; every later call blocks until that first run completes, then returns immediately without re-running. It is the idiomatic, race-free way to do lazy one-time initialization.
Real-World Scenario
A package exposes a shared database connection pool. The pool is expensive to create, so it's built lazily on first use. Wrapping the construction in `sync.Once` ensures that even if 100 goroutines call `GetPool()` simultaneously at startup, the pool is created exactly once.
Quick Snippet
snippet.go
import "sync"
var (
once sync.Once
instance *Database
)
func GetDatabase() *Database {
once.Do(func() {
// Runs exactly once, even under concurrent calls
instance = connectToDatabase()
})
return instance
}Full Example
once.go
// Compile: go run once.go
// Output:
// initializing database (expensive)
// instance id: 1
// all 10 goroutines got the same instance: true
package main
import (
"fmt"
"sync"
)
type Database struct{ id int }
var (
once sync.Once
instance *Database
)
func getDatabase() *Database {
once.Do(func() {
fmt.Println("initializing database (expensive)")
instance = &Database{id: 1}
})
return instance
}
func main() {
results := make([]*Database, 10)
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(idx int) {
defer wg.Done()
results[idx] = getDatabase()
}(i)
}
wg.Wait()
fmt.Println("instance id:", instance.id)
same := true
for _, r := range results {
if r != instance {
same = false
}
}
fmt.Println("all 10 goroutines got the same instance:", same)
}
Run command
go run once.go