Варианты:
1. Защищать value в map.
type MyMap map{Key]*Value
type Value struct{
sync.RWMutex
value
}
-- пара миллионов замков и добавлять/удалять записи небезогасно
2. Из функционального мира, перерасчитывать данные в новую мапу, потом подменять.
-- большая нагрузка на GarbageCollector.
3. Для вашего частного случая можно еще
sync.atomic
type M map[Key]*unsafe.Pointer
type Value *YorValueType
var old, changed Value
m := make(M)
v := unsafe.Pointer(old)
m[key] = &v
old = (*Value)(*m[key])
changed := DoSomething(*old)
atomic.StorePointer(m["foo"], unsafe.Pointer(&changed)) //Здесь атомарно подменяется ссылка
-- много редиректов и добавлять/удалять записи небезогасно
4. Разбить мапу на куски
[]map[Key]Value
или
map[Key1]struct{
sync.RWMutex
map[key2]Value
}
блокировать только необходимые куски.
-- многоуровневый доступ, куски все равно нужно блокировать, добавлять/удалять записи небезогасно