sync.Onceとは
syncパッケージの処理はこちらで説明されてたので、ご参考までにどうぞ
https://qiita.com/t-mochizuki/items/80dc959b4221c53f3c40#synconce
実際に試してみた
PatternA
とりあえずsync.Onceを使った場合と使わない場合を織り交ぜてみた
テストコード
package main
import "fmt"
import "sync"
var foo string
func main() {
var once sync.Once
once.Do(func() {
foo = "A"
})
once.Do(func() {
foo = "B"
})
fmt.Println(foo)
foo = "C"
fmt.Println(foo)
once.Do(func() {
foo = "D"
})
fmt.Println(foo)
}
結果
A
C
C
PatternB
PatternAで foo
が D
にかわらなかったのが、C
が代入されていたからか、そのまえにsync.Onceを使っていたからかを切り分ける
テストコード
package main
import "fmt"
import "sync"
var foo string
func main() {
var once sync.Once
foo = "C"
once.Do(func() {
foo = "D"
})
fmt.Println(foo)
}
結果
D
PatternC
異なる処理を同じ sync.Once を使った場合にどうなるかを確認
テストコード
package main
import "fmt"
import "sync"
var foo string
var bar string
func main() {
var once sync.Once
foo = "NoN"
bar = "NoN"
once.Do(func() {
foo = "A"
})
once.Do(func() {
bar = "B"
})
fmt.Printf("foo: %s\n",foo)
fmt.Printf("bar: %s\n",bar)
}
結果
foo: A
bar: NoN
PatternD
異なる処理を異なる sync.Once を使った場合にどうなるかを確認
テストコード
package main
import "fmt"
import "sync"
var foo string
var bar string
func main() {
var typea sync.Once
var typeb sync.Once
foo = "NoN"
bar = "NoN"
typea.Do(func() {
foo = "A"
})
typeb.Do(func() {
bar = "B"
})
fmt.Printf("foo: %s\n",foo)
fmt.Printf("bar: %s\n",bar)
}
結果
foo: A
bar: B
結論
- sync.Onceは宣言した変数別に管理される
- 中の処理が異なっていても関係ない。異なる処理を同じSync.Onceで管理してはいけない
当然といったら当然な結果でした。