Weak and concurrent hash map for caching
Hello,
I have written a very simple cache class with both weakness and concurrency benefits. This class is intended to be used as a weak cache in "hot redeploy" capable servers (JBoss or any other).
My implementation uses the (problematic) "double-check" pattern with a reentrant lock and encapsulates a WeakHashMap with WeakReference values (to avoid circular key/value references). Here is the code:
publicinterface ValueCreator<V>{
public V create();
}
publicclass WeakCache<K, V>{
privatefinal Lock lock =new ReentrantLock();
privatefinal Map<K, WeakReference><V>> weakMap;
public WeakCache(){
this(16);
}
public WeakCache(int initialCapacity){
this(initialCapacity, 0.75F);
}
public WeakCache(int initialCapacity,float loadFactor){
weakMap =new WeakHashMap<K, WeakReference><V>>(initialCapacity, loadFactor);
}
public V get(K key, ValueCreator<V> creator){
WeakReference<V> ref = weakMap.get(key);
if (ref ==null){
lock.lock();
try{
ref = weakMap.get(key);
if (ref ==null){
ref =new WeakReference<V>(creator.create());
weakMap.put(key, ref);
}
}finally{
lock.unlock();
}
}
return ref.get();
}
One usage of this cache is for session ejb3 lookup:
...
privatestaticfinal WeakCache<Class, Object> LOOKUP_CACHE =new WeakCache<Class, Object>();
...
publicstatic <T> T lookup(final Class<T> serviceClass){
T service = (T)LOOKUP_CACHE.get(serviceClass,
new ValueCreator<Object>(){
public T create(){
String lookup ="myapp/" + serviceClass.getSimpleName() +"/local";
try{
return (T)(new InitialContext()).lookup(lookup);
}catch (NamingException e){
thrownew RuntimeException("Could not lookup EJB " + serviceClass +": " + lookup, e);
}
}
}
);
return service;
}
...
2 questions:
1. Is there any issue with concurrent access to this cache ?
2. What happens exactly when the garbage collector wants to free memory with a map with both weak keys and values ?
Some limited tests show that the behavior of this cache fits my needs: the lookup cache is cleared on redeploy and it keeps its key/values pairs otherwise.
Thanks for any comments.
Message was edited by:
fwolff999

