golang Map 并发安全的几个点

实现1

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
//
// map_safe.go
// Copyright (C) 2018 chentao <chentao@chentaos-MacBook-Pro.local>
//
// Distributed under terms of the MIT license.
//
package main
import (
"fmt"
"sync"
"time"
)
type ctr struct {
sync.RWMutex
m map[string]int
}
func main() {
counter := &ctr{m: make(map[string]int)}
for i := 0; i < 10; i++ {
go bc(counter)
}
//for i := 0; i < 10; i++ {
// go set(counter, i*10)
//}
//for i := 0; i < 10; i++ {
// go get(counter)
//}
time.Sleep(time.Second * 2)
}
func bc(counter *ctr) {
for i := 0; i < 10; i++ {
go set(counter, i)
}
for i := 0; i < 10; i++ {
go get(counter)
}
}
// counter 这里必须是引用
func set(counter *ctr, v int) {
counter.Lock()
defer func() {
counter.Unlock()
fmt.Printf("set unlock mutex addr %p \n", &counter.RWMutex)
fmt.Printf("set unlock count addr %p \n", &counter.m)
fmt.Printf("set unlock all addr %p \n", &counter)
}()
//counter.m["some_key"] = v
counter.m["some_key"] = counter.m["some_key"] + v
//time.Sleep(time.Millisecond * 10)
fmt.Println("some_key set:", counter.m["some_key"])
}
func get(counter *ctr) {
counter.RLock()
defer func() {
counter.RUnlock()
fmt.Printf("get unlock mutex addr %p \n", &counter.RWMutex)
fmt.Printf("get unlock count addr %p \n", &counter.m)
fmt.Printf("get unlock all addr %p \n", &counter)
}()
n := counter.m["some_key"]
fmt.Println("some_key get:", n)
}

实现2

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
//
// map_safe.go
// Copyright (C) 2018 chentao <chentao@chentaos-MacBook-Pro.local>
//
// Distributed under terms of the MIT license.
//
package main
import (
"fmt"
"sync"
"time"
"unsafe"
)
type ctr2 struct {
sync.RWMutex
m map[string]int
}
func main() {
counter := ctr2{m: make(map[string]int)}
for i := 0; i < 10; i++ {
go counter.bc()
}
//for i := 0; i < 10; i++ {
// go set(counter, i*10)
//}
//for i := 0; i < 10; i++ {
// go get(counter)
//}
time.Sleep(time.Second * 2)
}
// counter这里都OK
func (counter *ctr2) bc() {
for i := 0; i < 10; i++ {
go counter.set(i)
}
for i := 0; i < 10; i++ {
go counter.get()
}
}
func (counter *ctr2) set(v int) {
counter.Lock()
defer func() {
counter.Unlock()
fmt.Printf("set unlock mutex addr %p \n", &counter.RWMutex)
fmt.Printf("set unlock count addr %p \n", &counter.m)
fmt.Printf("set unlock all addr %p \n", &(*counter))
fmt.Printf("set unlock all addr %p \n", unsafe.Pointer(counter))
fmt.Printf("set unlock all addr %p \n", counter)
}() // 注意这几个对象引用和地址的区分
//counter.m["some_key"] = v
counter.m["some_key"] = counter.m["some_key"] + v
//time.Sleep(time.Millisecond * 10)
fmt.Println("some_key set:", counter.m["some_key"])
}
func (counter *ctr2) get() {
counter.RLock()
defer func() {
counter.RUnlock()
fmt.Printf("get unlock mutex addr %p \n", &counter.RWMutex)
fmt.Printf("get unlock count addr %p \n", &counter.m)
fmt.Printf("get unlock all addr %p \n", &(*counter))
fmt.Printf("get unlock all addr %p \n", unsafe.Pointer(counter))
fmt.Printf("get unlock all addr %p \n", counter)
}()
n := counter.m["some_key"]
fmt.Println("some_key get:", n)
}