File tree Expand file tree Collapse file tree 2 files changed +98
-1
lines changed Expand file tree Collapse file tree 2 files changed +98
-1
lines changed Original file line number Diff line number Diff line change 1
1
# sync.Once
2
2
3
+ ## 定义
4
+
3
5
Once是sync包里的一个结构体类型,Once可以在并发场景下让某个操作只执行一次,比如设计模式里的单例只创建一个实例,比如只加载一次配置文件,比如对同一个channel只关闭一次(对一个已经close的channel再次close会引发panic)等。
4
6
5
7
定义如下:
@@ -55,7 +57,58 @@ func main() {
55
57
56
58
57
59
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
+ ## 注意事项
59
112
60
113
* Once变量作为函数参数传递时,只能传指针,不能传值。传值给函数A的话,对于函数A而言,参数列表里的once形参会是一个新生成的once局部变量,和外部传入的once实参不一样。
61
114
Original file line number Diff line number Diff line change
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
+ }
You can’t perform that action at this time.
0 commit comments