我有一个结构,MyStruct
其中包含一个地图。我想让对地图的访问对并发读写安全,但我也想坚持基础Map
而不是使用sync.Map
.
出于这个原因,我创建了MyStruct
受互斥锁保护的插入、删除和获取方法。代码看起来像这样
type MyStruct struct {
mu sync.Mutex
myMap map[string]string
}
func (myStruct *MyStruct) Add(val string) {
myStruct.mu.Lock()
myStruct.myMap[val] = val
myStruct.mu.Unlock()
}
func (myStruct *MyStruct) Remove(val string) {
myStruct.mu.Lock()
delete(myStruct.myMap, val)
myStruct.mu.Unlock()
}
func (myStruct *MyStruct) Fetch(val string) string {
myStruct.mu.Lock()
ret := delete(myStruct.myMap, val)
myStruct.mu.Unlock()
return ret
}
到目前为止,一切都很好。
一些客户MyStruct
虽然也需要循环,但myStruct.myMap
我的问题来了。哪个是最好的设计来使并发安全的循环操作不在 MyStruct 的方法中执行?目前我看到 2 个选项
- 将地图
myMap
和互斥锁设为公共mu
,MyStruct
并将责任转移给客户端,以确保循环线程安全。这很简单,但不知何故,感觉好像MyStruct
不太关心它的客户 - 保持一切私密,并添加一个方法,将地图副本返回给想要安全使用它的客户。从“封装”的角度来看,这似乎更好,但同时听起来有点沉重
还有其他可能吗?关于哪种设计更好的建议?