Я не уверен, что подхожу к этому правильно, идея в том, чтобы иметь параллелизм при чтении, но блокировать только при записи, обновлении или удалении.
type Data struct {
sync.RWMutex
fooMap map[string]Foo
}
func (d *Data) AddFoo(foo Foo) {
d.Lock()
defer d.Unlock()
d.fooMap[foo.getName()] = foo
}
func (d *Data) GetFoo(name string) Foo {
return d.fooMap[name]
}
func (d *Data) RemoveFoo(name string) Foo {
d.Lock()
defer d.Unlock()
var foo = self.fooMap[name]
if foo != nil {
delete(d.fooMap, name)
}
return foo
}
func (d *Data) HasFoo(name string) bool {
return d.fooMap[name] != nil
}
В поисках эффективного подхода, при котором я не блокирую при чтении из словаря, а блокирую только в методах AddFoo
и RemoveFoo
.
Редактировать
Контекст немного отличается, код не будет выполняться goroutines
, но будет использоваться на сервере, где происходит множество одновременных запросов.
Редактировать 2 В случае двух карт
type Data struct {
sync.RWMutex
BarMutex sync.RWMutex{}
fooMap map[string]Foo
barMap map[string]Bar
}
// for Foo
func (d *Data) AddFoo(foo Foo) {
d.Lock()
defer d.Unlock()
d.fooMap[foo.getName()] = foo
}
func (d *Data) GetFoo(name string) Foo {
return d.fooMap[name]
}
// for Bar
func (d *Data) AddBar(bar Bar) {
d.BarMutex.Lock()
defer d.BarMutex.Unlock()
d.barMap[bar.getName()] = bar
}
func (d *Data) GetBar(name string) Bar {
d.BarMutex.RLock()
defer d.BarMutex.RUnlock();
return d.barMap[name]
}
Добавление еще нескольких методов.