Appearance
MAP
键值对关联数组
- map集合使用前一定先要make
- map 键值对是无序的
- map key值是不重复的
go
//方式1:通过make定义
var map1 map[int]string = make(map[int]string, 10)
map1[1] = "张三"
map1[2] = "王五"
fmt.Println(map1)
//方式2:通过make定义 不指定长度
var map2 map[int]string = make(map[int]string)
map2[1] = "张三"
fmt.Println(map2)
//方式3: 键值对初始化
map3 := map[int]string{
1: "张三",
2: "王五",
}
fmt.Println(map3)
常规操作
go
//增删改
var map4 map[int]string = make(map[int]string)
map4[3] = "王五" //增加
map4[3] = "李四" //修改
delete(map4, 3) //删除
fmt.Println(map4)
//遍历1
for i := 0; i < len(map4); i++ {
fmt.Println(map4[i])
}
//遍历2
for key, value := range map4 {
fmt.Println(key, value)
}
并发锁
互斥锁
- 基于sync.Mutex执行的互斥锁
- 适用于读写不确定场景,即读写次数没有明显的区别的场景。
读写锁
- 基于sync.RWMutex执行的读写锁
- 适用于读多写少的场景。
sync.map
- go自带的map锁,底层通分离读写map和原子指令来实现读的近似无锁,并通过延迟更新的方式来保证读的无锁化。
- 读多修改少,元素增加删除频率不高的情况
分片锁
- 基于读写锁再次优化。将这个 map 分成 n 块,每个块之间的读写操作都互不干扰,从而降低冲突的可能性。
- 常使用高并发场景。减少锁的竞争。
go
package main
import (
"fmt"
"github.com/zeromicro/go-zero/core/hash"
"sync"
"time"
)
// 代表互斥锁
type MutexMap struct {
sync.Mutex
m map[string]int
}
// 代表读写锁
type RWMutexMap struct {
sync.RWMutex
m map[string]int
}
// 分片锁
const N = 32
type SafeMap struct {
locks [N]sync.RWMutex
maps [N]map[string]int
}
var mutexMap *MutexMap
var rwMutexMap *RWMutexMap
var syncMap *sync.Map
func main() {
mutexMap = &MutexMap{m: make(map[string]int, 100)}
rwMutexMap = &RWMutexMap{m: make(map[string]int, 100)}
syncMap = &sync.Map{}
sm := &SafeMap{}
for i := 0; i < N; i++ {
sm.maps[i] = make(map[string]int)
}
//互斥锁
for i := 0; i < 10; i++ {
go func() {
mutexMap.Lock()
mutexMap.m["a"] = i
mutexMap.Unlock()
fmt.Printf("%+v \r\n", mutexMap)
}()
}
time.Sleep(1 * time.Second)
fmt.Printf("最终: %+v \r\n", mutexMap)
//读写锁
for i := 0; i < 10; i++ {
go func() {
rwMutexMap.Lock()
rwMutexMap.m["b"] = i
rwMutexMap.Unlock()
fmt.Printf("%+v \r\n", rwMutexMap)
}()
}
time.Sleep(1 * time.Second)
fmt.Printf("最终: %+v \r\n", rwMutexMap)
//sync.map
for i := 0; i < 10; i++ {
go func() {
syncMap.Store("c", i)
fmt.Printf("%+v \r\n", syncMap)
}()
}
time.Sleep(1 * time.Second)
fmt.Printf("最终: %+v \r\n", syncMap)
//分片锁
key := "key"
index := hash.Hash([]byte(key)) % N
sm.locks[index].RLock()
value := sm.maps[index][key]
sm.locks[index].RUnlock()
fmt.Printf("最终: %+v \r\n", value)
}