单例实现
sync.Once
sync.Once
sync.Once源码分析
1. lock并不会同步值
在lock和unlock之间修改值,并不会保证对其他协程是可见的,除非使用相同的Mutex加锁,想要同步值必须使用atomic;
happen-before
happen-before
如果一个操作happens-before(之前发生)另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前。
两个操作之间存在happens-before关系,并不意味着一定要按照happens-before原则制定的顺序来执行。如果重排序之后的执行结果与按照happens-before关系来执行的结果一致,那么这种重排序并不非法。
2. Do执行一次
DodoneDo
3. Once执行Do后不准copy
A Once must not be copied after first use.
sync.OnceDodoneDo
4. Do并发时阻塞
Do
Instance2()
等到先调用的完成后再拿到返回值;
nil
deferf()doneDodone==0
m.Lock()
5. Do递归死锁
DoDosync.Mutex.Lock()
参考
- 《Go语言高级编程》
- Go1.16源码