Onceとは?
syncパッケージで定義されている。
Onceはアクションを1度のみ実行するオブジェクト。
OnceにはDoメソッドが定義されている。
Doメソッドは引数として渡された関数を、Onceのインスタンスで初めて呼び出される場合にのみ呼び出す。
- Doメソッドを複数回実行しても、引数の関数を呼び出すのは初回のみ
- 引数の関数が異なっていても、呼び出すのは初回のみ(同じOnceインスタンスであれば引数は関係ない)
- 異なるゴルーチンで呼ばれたとしても、1度しか実行しない
Onceのサンプルコード
変数count
を10個のゴルーチンからインクリメントしている。
ただし、インクリメントの関数はOnce.Doで呼び出しています。
package main import ( "fmt" "sync" ) func main() { var count int increment := func() { count++ } var once sync.Once var wg sync.WaitGroup wg.Add(10) for i := 0; i < 10; i++ { go func() { defer wg.Done() once.Do(increment) }() } wg.Wait() fmt.Printf("Count: %d\n", count) }
Go Playground: https://play.golang.org/p/cJ8r_meJm9n
結果は、「Count: 1」
異なるゴルーチン間でもOnce.Doに渡した関数が1度しか呼び出されていないのが確認できます。
参考図書
Tour of Goを終えた人にオススメです!!