通过sync/atomic 包的原子操作对原始类型s(int32
, int64
, etc.) 进行操作的时候,很容易忘记在对变量进行读取和修改的时候,使用原子操作。
而go.uber.org/atomic包通过隐藏基础类型对这些操作增加了类型安全,另外,它还包括了一个方便的atomic.Bool类型。
Bad
type foo struct {
running int32 // 原子类型
}
func (f* foo) start() {
//原子操作
if atomic.SwapInt32(&f.running, 1) == 1 {
// 已经在运行了
return
}
// start the Foo
}
func (f *foo) isRunning() bool {
return f.running == 1 // 忘记使用原子操作导致资源竞争
}
Good
type foo struct {
running atomic.Bool //使用atomic.Bool类型
}
func (f *foo) start() {
//使用Swap(true)进行安全判断
if f.running.Swap(true) {
// already running…
return
}
// start the Foo
}
func (f *foo) isRunning() bool {
//使用Load()方法保证安全
return f.running.Load()
}