Week03: Go并发编程(八) 深入理解 sync.Once
本系列为极客时间 Go 进阶训练营笔记,同步直播更新,预计一周更新 1 ~ 2 篇文章,到 202103 月更新完成
在上一篇文章《Week03: Go 并发编程(七) 深入理解 errgroup》当中看 errgourp
源码的时候我们发现最后返回 err
是通过 once 来只保证返回一个非 nil 的值的,本文就来看一下 Once 的使用与实现
案例
once 的使用很简单
1 |
|
输出
1 |
|
源码分析
1 |
|
done 用于判定函数是否执行,如果不为 0 会直接返回
1 |
|
看 go 的源码真的可以学到很多东西,在这里还给出了很容易犯错的一种实现
1 |
|
如果这么实现最大的问题是,如果并发调用,一个 goroutine 执行,另外一个不会等正在执行的这个成功之后返回,而是直接就返回了,这就不能保证传入的方法一定会先执行一次了
所以回头看官方的实现
1 |
|
会先判断 done 是否为 0,如果不为 0 说明还没执行过,就进入 doSlow
1 |
|
在 doSlow
当中使用了互斥锁来保证只会执行一次
总结
- Once 保证了传入的函数只会执行一次,这常用在单例模式,配置文件加载,初始化这些场景下
- 但是需要注意。Once 是不能复用的,只要执行过了,再传入其他的方法也不会再执行了
- 并且 Once.Do 在执行的过程中如果 f 出现 panic,后面也不会再执行了
参考文献
关注我获取更新
看到这里了还不关注点赞走一波
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!