This isn't really thread safe. The caller might see the wrong cache instance, or see a partially initialized one. Either cache must be volatile, or you need some synchronization around looking at the cache field and running the updateCache() method to replace its contents with a new map.

This used to work because everything was synchronized together inside of a single refresh() method.