Skip to content

Instantly share code, notes, and snippets.

@meson10
Created June 28, 2016 05:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save meson10/d46baf8bf5b38525f83caa7f448b3163 to your computer and use it in GitHub Desktop.
Save meson10/d46baf8bf5b38525f83caa7f448b3163 to your computer and use it in GitHub Desktop.
Go singleton as locks or sync.Once
package main
import (
"log"
"sync"
)
type MyStruct struct {
field int
}
var onceCached *MyStruct
var lockCached = struct {
sync.RWMutex
val *MyStruct
}{}
func initMyStruct() MyStruct {
return MyStruct{field: 1}
}
var once sync.Once
func getIntOnce(ident int) *MyStruct {
log.Println("No lock", ident)
once.Do(func() {
log.Println("Initializing GetInt")
x := initMyStruct()
onceCached = &x
})
log.Println("No lock return", ident)
return onceCached
}
func getIntLock(ident int) *MyStruct {
lockCached.Lock()
log.Println("lock", ident)
if lockCached.val == nil {
log.Println("Initializing GetInt")
x := initMyStruct()
lockCached.val = &x
}
lockCached.Unlock()
log.Println("lock freed", ident)
return lockCached.val
}
func goGetInt(getter func(int) *MyStruct) {
var wg sync.WaitGroup
wg.Add(2)
log.Println(getter(0))
go func() {
defer wg.Done()
log.Println(getter(1))
}()
go func() {
defer wg.Done()
log.Println(getter(2))
}()
wg.Wait()
}
func main() {
goGetInt(getIntOnce)
log.Println("******************")
goGetInt(getIntLock)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment