golang内存模型-3 once解决Happens Before

112 阅读1分钟

你要尽全力保护你的梦想。那些嘲笑你梦想的人,因为他们必定会失败,他们想把你变成和他们一样的人。 ---《当幸福来敲门》

详细文章请移步到微信公众号中阅读: golang内存模型-3 once解决Happens Before

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

希望大家关注哈,原创不容易,求点赞,求关注,求分享

扫码_搜索联合传播样式-标准色版.png