I'd like to implement a simple caching of heavyweight objects in a web java application. But I can't figure out how to do it properly.
Am I missing something or ConcurrentHashMap methods (putIfAbsent, ...) are not enough and additional synchronization is needed ?
Is there a better simple API (In memory storage, no external config) to do this ?
P.
If it is safe to temporarily have more than one instance for the thing you're trying to cache, you can do a "lock-free" cache like this:
public Heavy instance(Object key) {
Heavy info = infoMap.get(key);
if ( info == null ) {
// It's OK to construct a Heavy that ends up not being used
info = new Heavy(key);
Heavy putByOtherThreadJustNow = infoMap.putIfAbsent(key, info);
if ( putByOtherThreadJustNow != null ) {
// Some other thread "won"
info = putByOtherThreadJustNow;
}
else {
// This thread was the winner
}
}
return info;
}
Multiple threads can "race" to create and add an item for the key, but only one should "win".