go sync.Map簡介與使用
阿新 • • 發佈:2018-12-01
看程式碼:
package main
func main() {
m := make(map[int]int)
go func() {
for {
m[1] = 1
}
}()
go func() {
for {
_ = m[1]
}
}()
select {
}
}
出錯:fatal error: concurrent map read and map write, 一看就懂
怎麼辦?
package main import ( "fmt" "sync" ) func main() { var m sync.Map go func() { for { m.Store(1, 1) } }() go func() { for { _, _= m.Load(1) } }() fmt.Println("wait") select { } }
OK了。
再來看看sync.Map的用法:
package main import ( "fmt" "sync" ) func main() { var m sync.Map m.Store("linzhiling", 100) m.Store("taoge", 99) m.Store("fanbingbing", 98) fmt.Println(m.Load("taoge")) m.Delete("fanbingbing") m.Range(func(k, v interface{}) bool { fmt.Println(k, v) return true }) }
結果:
99 true
linzhiling 100
taoge 99
最後再來看點程式碼:
package main
import (
"fmt"
"sync"
"strconv"
"encoding/json"
)
const (
BATCH = 3
)
func convert(sm sync.Map) ([]string, []string, error) {
keys := make([]string, 0)
values := make([]string, 0)
i := 0
j := 0
datas := make(map[int]interface{}, 0)
var err error
sm.Range(func(k, v interface{}) bool {
datas[k.(int)] = v
i++
if i == BATCH {
j++
buf, e := json.Marshal(datas)
if e != nil {
err = e
return true
}
keys = append(keys, strconv.Itoa(j))
values = append(values, string(buf))
datas = make(map[int]interface{}, 0)
i = 0
}
return true
})
if i != 0 {
buf, e := json.Marshal(datas)
if e != nil {
err = e
return keys, values, err
}
keys = append(keys, strconv.Itoa(j + 1))
values = append(values, string(buf))
_ = buf
}
return keys, values, err
}
func main() {
var m sync.Map
m.Store(10001, 100)
m.Store(10002, 99)
m.Store(10003, 98)
m.Store(10004, 97)
m.Store(10005, 96)
m.Store(10006, 95)
m.Store(10007, 94)
m.Store(10008, 93)
id, value, _ := convert(m)
fmt.Println(id)
fmt.Println(value)
}
結果:
[1 2 3]
[{"10004":97,"10005":96,"10006":95} {"10001":100,"10007":94,"10008":93} {"10002":99,"10003":98}]
不多說。