I\'ve got a web application where people ask for resources. This resources are cached using a synchronized hash map for efficiency. The problem here is when two different re
One possible problem is that you create unnecessary contention by executing veryCostlyOperation()
inside a synchronized
block, so that many threads cannot retrieve their (independent) resources at the same time. This can be solved by using Future
as values of the map:
Map> map = new ConcurrentHashMap>();
...
Future r = map.get(name);
if (r == null) {
FutureTask task = null;
synchronized (lock) {
r = map.get(name);
if (r == null) {
task = new FutureTask(new Callable() {
public Resource call() {
return veryCostlyOperation(name);
}
});
r = task;
map.put(name, r);
}
}
if (task != null) task.run(); // Retrieve the resource
}
return r.get(); // Wait while other thread is retrieving the resource if necessary