设计思路
- 使用
sync.Map
来处理多个goroutine的并发读写操作,因为sync.Map
是线程安全的,适合这种场景。
- 为了统计不同类型数据的数量,我们可以使用另一个
sync.Map
来存储每种类型数据的计数。
- 对于数据的读取、写入和删除操作,我们分别定义对应的函数,在这些函数中对
sync.Map
进行操作,并同时更新类型计数的sync.Map
。
完整代码
package main
import (
"fmt"
"sync"
)
// Data 用于存储不同类型的数据
type Data struct {
value interface{}
}
func main() {
var wg sync.WaitGroup
mainMap := sync.Map{}
typeCountMap := sync.Map{}
// 模拟多个goroutine进行操作
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
// 写入操作
writeData(&mainMap, &typeCountMap, Data{value: fmt.Sprintf("string-%d", id)})
// 读取操作
readData(&mainMap, fmt.Sprintf("string-%d", id))
// 删除操作
deleteData(&mainMap, &typeCountMap, fmt.Sprintf("string-%d", id))
}(i)
}
wg.Wait()
// 输出每种类型数据的数量
typeCountMap.Range(func(key, value interface{}) bool {
fmt.Printf("Type %v count: %v\n", key, value)
return true
})
}
// writeData 写入数据到mainMap,并更新typeCountMap
func writeData(mainMap *sync.Map, typeCountMap *sync.Map, data Data) {
mainMap.Store(data.value, data)
typeKey := fmt.Sprintf("%T", data.value)
typeCountMap.Store(typeKey, getTypeCount(typeCountMap, typeKey)+1)
}
// readData 从mainMap读取数据
func readData(mainMap *sync.Map, key interface{}) {
value, ok := mainMap.Load(key)
if ok {
fmt.Printf("Read data: %v\n", value)
} else {
fmt.Printf("Data with key %v not found\n", key)
}
}
// deleteData 从mainMap删除数据,并更新typeCountMap
func deleteData(mainMap *sync.Map, typeCountMap *sync.Map, key interface{}) {
mainMap.Delete(key)
typeKey := fmt.Sprintf("%T", key)
count := getTypeCount(typeCountMap, typeKey)
if count > 0 {
typeCountMap.Store(typeKey, count-1)
}
}
// getTypeCount 获取typeCountMap中指定类型的计数
func getTypeCount(typeCountMap *sync.Map, typeKey string) int {
value, ok := typeCountMap.Load(typeKey)
if ok {
return value.(int)
}
return 0
}