Once 結(jié)構(gòu)體 和 Go()方法都是位于 sync 包下懂酱,主要為了保證 Do(func) 中的 func 只執(zhí)行一次樱拴,用于單例模式是比較好的方案爹土。
原理:
Once 結(jié)構(gòu)體中纺且,包含兩個字段
type Once struct {?
? ? ? ? done uint32 // 用來記錄func 已經(jīng)執(zhí)行的次數(shù)
? ? ? ? m Mutex ? ? ?// 鎖
}
func (o *Once) Do(f func()) {
? ? ? ? if atomic.LoadUint32(&o.done) == 0 { ? // 利用 atomic 包中的方法保證計數(shù)同步
? ? ? ? ? ? ? ? o.doSlow(f) ? ?// 執(zhí)行方法帮坚,記錄標(biāo)記字段
? ? ? ? }
?}
func (o *Once) doSlow(f func()) {
? ? ? ? o.m.Lock() ?// 鎖住執(zhí)行狀態(tài)
? ? ? ? defer o.m.Unlock() ?// 釋放鎖
? ? ? ? if o.done == 0 { ?// 如果沒執(zhí)行過
? ? ? ? ? ? ? ? defer atomic.StoreUint32(&o.done, 1) // 記錄已經(jīng)執(zhí)行過
? ? ? ? f() // 執(zhí)行函數(shù)
? ? ? ? }
}