一次性操作 - sync.Once #
sync.Once用来完成一次性操作,比如配置加载,单例对象初始化等。
源码分析 #
sync.Once定义如下:
type Once struct {
done uint32 // 用来标志操作是否操作
m Mutex // 锁,用来第一操作时候,加锁处理
}
接下来看剩下的全部代码:
func (o *Once) Do(f func()) {
if atomic.LoadUint32(&o.done) == 0 {// 原子性加载o.done,若值为1,说明已完成操作,若为0,说明未完成操作
o.doSlow(f)
}
}
func (o *Once) doSlow(f func()) {
o.m.Lock() // 加锁
defer o.m.Unlock()
if o.done == 0 { // 再次进行o.done是否等于0判断,因为存在并发调用doSlow的情况
defer atomic.StoreUint32(&o.done, 1) // 将o.done值设置为1,用来标志操作完成
f() // 执行操作
}
}