你要尽全力保护你的梦想。那些嘲笑你梦想的人,因为他们必定会失败,他们想把你变成和他们一样的人。---《当幸福来敲门》
1. 前言
继上篇文章我们介绍了锁在解决HappensBefore的重要作用,接下来这片文章我们来聊聊once是怎么满足HappensBefore的。
2. 例子
还是上篇文章销毁goroutine的例子
package main var a string func hello() { go func() { a = "hello" }() print(a) } func main() { hello() }
我们说这个例子有问题,上篇文章说了,就是结果不确定,那么我们如何通过once来解决呢?
3. 解决
sync包的Once为多个goroutine提供了安全的初始化机制。能在多个线程中执行once.Do(f),但只有一个f()会执行,其他调用会一直阻塞直到f()返回。通过执行先行发生(指f()返回)于其他的返回。例如:
package main import ( "sync" "time" ) var a string var once sync.Once func setup() { a = "hello" } func hello() { once.Do(setup) print(a) } func main() { go hello() go hello() time.Sleep(100*time.Second) }
我们看到结果是打印两次hellohello,setup只在第一次调用hello()的时候执行一次。
hellohello
4. 小结
once的使用比较常见,更多的使用场景是对象只初始化一次的sense中。希望通过golang内存模型这三篇文章能够帮助到大家在写代码的时候如何应对HappensBefore。
5. 关注公众号
微信公众号:堆栈future