# 数据结构

type Once struct {
	done atomic.Uint32 // 0 = unused, 1 = used,用于标志操作是否操作
	m    Mutex // 锁,用来第一操作时候,加锁处理
}

# 源码

func (o *Once) Do(f func()) {
	// 快路径:无锁判断
	// 若已为 1,直接返回,避免加锁开销
	if o.done.Load() == 0 { 
		o.doSlow(f)
	}
}
func (o *Once) doSlow(f func()) {
	// 慢路径:有人看到 done ==0, 需要串行化进入临界区
	o.m.Lock()
	defer o.m.Unlock()
	// 双重检查:可能在当前 goroutine 申请到锁之前,别的 goroutine 已经把 f 执行过了
	if o.done.Load() == 0 {
		// 将 o.donw 值设置为 1,用来标记操作完成
		defer o.done.Store(1)
		// 真正执行业务函数
		f()
	}
}
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

ZJM 微信支付

微信支付

ZJM 支付宝

支付宝