LoginSignup
4
2

More than 5 years have passed since last update.

sync.Onceの挙動がなんとなくしか分からなかったので実際に試してみた

Last updated at Posted at 2018-03-23

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で fooD にかわらなかったのが、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で管理してはいけない

当然といったら当然な結果でした。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2