1) нет, ваша схема ненадежна. Вы не должны вызывать
cache.asMap().putIfAbsent(givenKey, givenObj);
с помощью метода документации guava. Cache.get (ключ K, вызываемый загрузчик) предпочтительнее, чем использовать методы asMap.
2) да, его можно оптимизировать. Вместо этого следует вызвать этот метод:
cache.get(K key, Callable<? extends V> loader)
Этот метод вернет значение, если оно уже находится в кеше, или добавит значение из загрузчика в кеш, еслизначение не находится в кеше и возвращает его.
, например:
MyObject objInCache = cache.get(givenKey, ()->givenObj)
if(!objInCache.equals(givenobj)){
//obje was in the cache,
//update object
}
3) вам не нужно использовать volatile, если кеш является поточно-ориентированным