util: synchronize cache access
This is to prevent multiple (potentially expensive) computations in parallel.
@@ -71,11 +71,17 @@ public class KillBillCacheController<K, V> implements CacheController<K, V> {
V value;
try {
+ if (!isKeyInCache(key)) {
+ synchronized (this) {
if (!isKeyInCache(key)) {
value = computeAndCacheValue(key, cacheLoaderArgument);
} else {
value = cache.get(key);
}
+ }
+ } else {
+ value = cache.get(key);
+ }
} catch (final CacheException e) {
logger.warn("Unable to retrieve cached value for key='{}' and cacheLoaderArgument='{}'", key, cacheLoaderArgument, e);
value = computeValue(key, cacheLoaderArgument);
@@ -135,8 +141,7 @@ public class KillBillCacheController<K, V> implements CacheController<K, V> {
return null;
}
- // Race condition, we may compute it for nothing
- putIfAbsent(key, value);
+ cache.put(key, value);
return value;
}
