slice在并发执行中不会报错, 但数据会丢失, 可以加锁解决; map在高并发执行中会直接报错, 需要加锁使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package main

import (
"fmt"
"sort"
"time"
)

var s []int

func appendValue(i int) {
s = append(s, i)
}

func main() {

for i := 0; i < 10000; i++ {
go appendValue(i)
}

sort.Ints(s) //给切片排序,先排完序再打印,

for i, v := range s {
fmt.Println(i, ":", v)

}

time.Sleep(5e9)

}

输出为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
0 : 0
1 : 0
2 : 0
3 : 0
4 : 0
5 : 0
6 : 0
7 : 0
8 : 0
9 : 0
10 : 0
11 : 0
12 : 0
13 : 0
14 : 0
15 : 0
16 : 0
17 : 0
18 : 0
19 : 0
20 : 0
21 : 0
22 : 0
23 : 0
24 : 0
25 : 0
26 : 0
27 : 0
28 : 0
29 : 0
30 : 0
31 : 0
32 : 0
33 : 0
34 : 0
35 : 0
36 : 0
37 : 0
38 : 0
39 : 0
40 : 0
41 : 0
42 : 0
43 : 0
44 : 0
45 : 0
46 : 0
47 : 0
48 : 0
49 : 0
50 : 0
51 : 0
52 : 0
53 : 0
54 : 0
55 : 0
56 : 0
57 : 0
58 : 0
59 : 0
60 : 0
61 : 0
62 : 0
63 : 0
64 : 0
65 : 0
66 : 0
67 : 0
68 : 0
69 : 0
70 : 0
71 : 0
72 : 0
73 : 0
74 : 0
75 : 0
76 : 0
77 : 0
78 : 0
79 : 0
80 : 0
81 : 0
82 : 0
83 : 0
84 : 0
85 : 1
86 : 2
87 : 3
88 : 6
89 : 8
90 : 12
91 : 13
92 : 14
93 : 19
94 : 28
95 : 30
96 : 31
97 : 32
98 : 33
99 : 34
100 : 35
101 : 36
102 : 44
103 : 45
104 : 46
105 : 47
106 : 48
107 : 49
108 : 50
109 : 51
110 : 52
111 : 53
112 : 54
113 : 55
114 : 56
115 : 57
116 : 58
117 : 59
118 : 60
119 : 61
120 : 62
121 : 63
122 : 64
123 : 65
124 : 66
125 : 67
126 : 68
127 : 69
128 : 70
129 : 71
130 : 72
131 : 73
132 : 74
133 : 75
134 : 76
135 : 77
136 : 78
137 : 79
138 : 80
139 : 81
140 : 82
141 : 83
142 : 84
143 : 85
144 : 86
145 : 87
146 : 88
147 : 89
148 : 90
149 : 91
150 : 92
151 : 93
152 : 94
153 : 95
154 : 96
155 : 97
156 : 98
157 : 99
158 : 100
159 : 101
160 : 102
161 : 103
162 : 104
163 : 105
164 : 106
165 : 107
166 : 108
167 : 109
168 : 110
169 : 111
...

8309 : 9970
8310 : 9971
8311 : 9972
8312 : 9973
8313 : 9974
8314 : 9976
8315 : 9977
8316 : 9978
8317 : 9979
8318 : 9980
8319 : 9981
8320 : 9982
8321 : 9983
8322 : 9984
8323 : 9985
8324 : 9986
8325 : 9987
8326 : 9988
8327 : 9989
8328 : 9990
8329 : 9991
8330 : 9992
8331 : 9993
8332 : 9995
8333 : 9996
8334 : 9994
8335 : 9997
8336 : 9998
8337 : 9999

没有到 9999 : 9999


加锁之后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

package main

import (
"fmt"
"sort"
"sync"
"time"
)

var s []int
var lock sync.Mutex

func appendValue(i int) {
lock.Lock()
s = append(s, i)
lock.Unlock()
}

func main() {

for i := 0; i < 10000; i++ {
go appendValue(i)
}

sort.Ints(s) //给切片排序,先排完序再打印,

for i, v := range s {
fmt.Println(i, ":", v)

}

time.Sleep(5e9)

}

输出为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
0 : 0
1 : 1
2 : 2
3 : 3
4 : 4
5 : 5
6 : 6
7 : 7
8 : 8
9 : 9
10 : 10
11 : 11
12 : 12
13 : 13
14 : 14

...

9992 : 9992
9993 : 9993
9994 : 9994
9995 : 9995
9996 : 9996
9997 : 9997
9998 : 9998
9999 : 9999

参考:

golang并发安全: slice和map并发不安全,及其解决方法