// mutexCache implements statCache, backed by a map and sync.RWMutex type mutexCache struct { src StatSource mtx sync.RWMutex lookup map[string]*statSet } func (mc *mutexCache) get(name string) *statSet { // take a read lock to see if the set already exists mc.mtx.RLock() set, ok := mc.lookup[name] mc.mtx.RUnlock() if ok { // the set exists, return it return set } // need to take a write lock to update the map mc.mtx.Lock() // While waiting for the write lock, another goroutine may have created the // set. Here, we check again after obtaining the lock before making a new one if set, ok = mc.lookup[name]; !ok { set = newStatSet(mc.src, name) mc.lookup[name] = set } mc.mtx.Unlock() return set }