Skip to content

Commit b4bd43b

Browse files
committed
update lesson22
1 parent 1bc7f6a commit b4bd43b

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

workspace/lesson22/readme.md

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# sync.Once
22

3+
## 定义
4+
35
Once是sync包里的一个结构体类型,Once可以在并发场景下让某个操作只执行一次,比如设计模式里的单例只创建一个实例,比如只加载一次配置文件,比如对同一个channel只关闭一次(对一个已经close的channel再次close会引发panic)等。
46

57
定义如下:
@@ -55,7 +57,58 @@ func main() {
5557

5658

5759

58-
## 注意事项
60+
## sync.Once实现并发安全的单例
61+
62+
```go
63+
package main
64+
65+
import (
66+
"fmt"
67+
"sync"
68+
)
69+
70+
type Singleton struct {
71+
member int
72+
}
73+
74+
var instance *Singleton
75+
76+
var once sync.Once
77+
78+
func getInstance() *Singleton {
79+
/*
80+
通过sync.Once实现单例,只会生成一个Singleton实例
81+
*/
82+
once.Do(func() {
83+
fmt.Println("once")
84+
instance = &Singleton{}
85+
instance.member = 100
86+
})
87+
fmt.Println(instance.member)
88+
return instance
89+
}
90+
91+
func main() {
92+
var wg sync.WaitGroup
93+
size := 10
94+
wg.Add(size)
95+
/*
96+
多个goroutine同时去获取Singelton实例
97+
*/
98+
for i:=0; i<size; i++ {
99+
go func() {
100+
defer wg.Done()
101+
instance = getInstance()
102+
}()
103+
}
104+
wg.Wait()
105+
fmt.Println("end")
106+
}
107+
```
108+
109+
110+
111+
## 注意事项
59112

60113
* Once变量作为函数参数传递时,只能传指针,不能传值。传值给函数A的话,对于函数A而言,参数列表里的once形参会是一个新生成的once局部变量,和外部传入的once实参不一样。
61114

workspace/lesson22/singleton.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"sync"
6+
)
7+
8+
type Singleton struct {
9+
member int
10+
}
11+
12+
var instance *Singleton
13+
14+
var once sync.Once
15+
16+
func getInstance() *Singleton {
17+
/*
18+
通过sync.Once实现单例,只会生成一个Singleton实例
19+
*/
20+
once.Do(func() {
21+
fmt.Println("once")
22+
instance = &Singleton{}
23+
instance.member = 100
24+
})
25+
fmt.Println(instance.member)
26+
return instance
27+
}
28+
29+
func main() {
30+
var wg sync.WaitGroup
31+
size := 10
32+
wg.Add(size)
33+
/*
34+
多个goroutine同时去获取Singelton实例
35+
*/
36+
for i:=0; i<size; i++ {
37+
go func() {
38+
defer wg.Done()
39+
instance = getInstance()
40+
}()
41+
}
42+
wg.Wait()
43+
fmt.Println("end")
44+
}

0 commit comments

Comments
 (0)