go基础库sync.Once使用

最近代码中需要使用sync.Once,mark下心得~

sync.Once顾名思义,就是能够实现多线程同步执行,且只执行一次,多用于单例模式。

如某个单例,在访问时才进行创建并初始化,这里就可以使用sync.Once。

sync.Once的源码如下,go版本1.12.7 windows/amd64:

package sync

import (
	"sync/atomic"
)

type Once struct {
	m    Mutex
	done uint32
}

func (o *Once) Do(f func()) {
	// 先检查o.done是否完成
	if atomic.LoadUint32(&o.done) == 1 {
		return
	}
	// Slow-path.
	// 加锁,避免多线程调用f()
	o.m.Lock()
	defer o.m.Unlock()
	if o.done == 0 {
		defer atomic.StoreUint32(&o.done, 1)
		f()
	}
}

说白了就是一个标识是否完成的标志,以及一个互斥量,并通过原子操作来读/写这个标志。

单例样例:

type Config struct {
	Name string
}

var c *Config
func getConfig() *Config {
	once.Do(func() {
		if c != nil {
			return
		}
		c = &Config{
			Name: "test",
		}
	})
	return c
}

你可能感兴趣的:(golang)