Once使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package main
import (
"fmt"
"sync"
)
func main() {
var once sync.Once
// 第一个初始化函数
f1 := func() {
fmt.Println("in f1")
}
once.Do(f1) // 打印出 in f1
// 第二个初始化函数
f2 := func() {
fmt.Println("in f2")
}
once.Do(f2) // 无输出
}
|
总结一下 Once 并发原语解决的问题和使用场景:Once 常常用来初始化单例资源,或者
并发访问只需初始化一次的共享资源,或者在测试的时候初始化一次测试资源。
使用 Once 可能出现的 2 种错误
第一种错误:死锁
你已经知道了 Do 方法会执行一次 f,但是如果 f 中再次调用这个 Once 的 Do 方法的话,
就会导致死锁的情况出现。这还不是无限递归的情况,而是的的确确的 Lock 的递归调用导
致的死锁。
1
2
3
4
5
6
7
8
|
func main() {
var once sync.Once
once.Do(func() {
once.Do(func() {
fmt.Println("初始化")
})
})
}
|