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 31
| 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 202
| 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 36 37
| 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 27
| 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并发不安全,及其解决方法
米哈游面试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package main
import ( "fmt" )
func main() {
var sli []int
for i := 0; i < 10; i++ {
go func() { sli = append(sli, 1) }() }
fmt.Println(len(sli))
}
|
这样一般会是0
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
| package main
import ( "fmt" )
func main() {
var sli []int
for i := 0; i < 10; i++ {
go func() { for j := 0; j < 10; j++ { sli = append(sli, 1) } }() }
fmt.Println(len(sli))
}
|
这样一般也是0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package main
import ( "fmt" "time" )
func main() {
var sli []int
for i := 0; i < 10; i++ {
go func() { sli = append(sli, 1) }() }
time.Sleep(time.Millisecond) fmt.Println(len(sli))
}
|
这样一般<10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package main
import ( "fmt" "time" )
func main() {
var sli []int
for i := 0; i < 10; i++ {
go func() { for j := 0; j < 10; j++ { sli = append(sli, 1) } }() }
time.Sleep(time.Microsecond) fmt.Println(len(sli))
}
|
一般<100
原文链接: https://dashen.tech/2019/01/17/golang之slice并发访问/
版权声明: 转载请注明出处.