2-4.sync.Once的实现
type Once struct {
done uint32 // 用来标识代码块是否执行过
m Mutex // 互斥锁
}
func (o *Once) Do(f func()) {
// done==0,说明没执行过,进入慢路径
if atomic.LoadUint32(&o.done) == 0 {
o.doSlow(f)
}
}
func (o *Once) doSlow(f func()) {
o.m.Lock()
defer o.m.Unlock()
if o.done == 0 { // 双重检查。因为可能有多个协程进入慢路径。第一个协程执行完毕后,后面的协程按顺序还能获取锁,此时再判断一次
defer atomic.StoreUint32(&o.done, 1) // 执行成功后将 done 变量修改为1
f()
}
}Last updated