HomeBlogProjects

Go sync.Once 原理

sorcererxw

sync.Once 用于保证一段任务执行 exactly once。它的实现非常简单:

type Once struct {
	done uint32
	m    Mutex
}

func (o *Once) Do(f func()) {
	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)
		f()
	}
}

可以看出 Once 的工作流程:

整个流程其实就是双检锁单例的实现,在锁的基础上引入了 double check,所以有下面几个点值得注意: