2 minutes reading time
在 go 语言中我们可以使用 sync.Once 对象来实现函数方法只执行一次的功能。
package main
import (
"fmt"
"sync"
)
func main()
输出:
hello 9
不使用 Sync.Once 的结果如下:
hello 9
hello 4
hello 0
hello 1
hello 2
hello 3
hello 6
hello 5
hello 7
hello 8
可以看到, 在使用 sync.Once 的情况下, 只执行一次函数。
通过查看源码,可以看到 Sync.Once 的源码十分简单。 只有一个结构体和2个方法。
type Once struct
done 成员用来判断函数是否执行过。
func (f func())
Do 方法的实现是这样的,检查 done 成员,如果为 0,则执行 f 函数。
接下来看看 doSlow 方法,它是一个锁的实现,它的实现如下:
func (f func())
doSlow 会执行函数 f,并且在执行完 f 后将 done 成员设置为 1。 在 doSlow 当中使用了互斥锁来保证只会执行一次
Once 保证了传入的函数只会执行一次,这常用在这些场景下:单例模式,配置文件加载,初始化。
Once 是不能复用的,只要执行过一个函数,其他函数就不能再次执行。