TL;DR

アトミック操作を保証する特別な変数。

なぜ必要か

x = x + 1 のような通常の変数への操作は、複数の命令に分割される。そのため、スレッド間でデータ競合が起きることがある。アトミック変数を使えば、これを 1 つの操作として扱える。

例

複数のスレッドが同じカウンタを同時に更新する場面で使う。たとえば、アクセス回数やタスクの完了数を数えるときである。

Go の sync/atomic パッケージには、atomic.Bool、atomic.Int64、atomic.Pointer[T]、atomic.Value などのアトミックな型がある。atomic.Int64 のゼロ値は 0 で、Add で値を足せる。

var counter atomic.Int64
counter.Add(5)
n := counter.Add(3)
fmt.Println(n) // 8

注意点

Go のドキュメントは、sync/atomic を同期のアルゴリズムを実装するための低レベルの部品としており、正しく使うには細心の注意が要るとしている。特別な場面以外では、チャネルや sync パッケージで同期するほうがよい。

関連

出典