sync.Once
- Go course
- Intermediate
- Lesson 22/80
- 4 min
Learn to run code exactly once with Once.
sync.Once
sync.Once ensures a function runs exactly once for the whole program. The once.Do(func) call runs on the first goroutine; later calls do nothing.
Once is ideal for lazy initialization: you prepare a variable on first use. The pattern var once sync.Once; once.Do(func(){ cfg = load() }) is common.
Once and initialization
Once is handy for loading global config. With once.Do(func(){ cfg = loadConfig() }) the config loads only on the first call; later calls return the existing cfg.
Since Once is thread-safe no extra mutex is needed. Do can always be called even if empty; after the first call it is a no-op.
Practice Print with Once
Inside main, add a sync.Once declaration and print once done with fmt.Println.
Starter code
package main
import "fmt"
func main() {
// buraya yaz
}Sample solution
package main
import (
"fmt"
"sync"
)
func main() {
var once sync.Once
once.Do(func() { fmt.Println("once tamam") })
}Expected output
once tamam
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What does sync.Once guarantee?
- Fast execution
- Exactly once execution Correct answer
- Infinite loop
- Sequential execution
Explanation: exactly once execution. Speed is not about Once, count is.
2 Once usage
var once sync.Once
var cfg *Config
func getCfg() *Config {
once.____(func() {
cfg = loadConfig()
})
return cfg
}
var once sync.Once
var cfg *Config
func getCfg() *Config {
once.Do(func() {
cfg = loadConfig()
})
return cfg
}
Explanation: Run and Call are not on Once.
3 Match Once concepts
| Term | Meaning |
|---|---|
Do |
Run once |
sync.Once |
Tip |
lazy init |
Lazy initialization |
thread-safe |
Safe |