I need to ensure that multiple threads aren't trying to access the same resource at the same time. I have a bunch of these resources, so I want to have a separate lock object for each resource (rather than one global lock) so that threads aren't unnecessarily blocking eachother.
Eddie presents a great solution for this using ConcurrentMap.putIfAbsent()
in https://stackoverflow.com/a/659939/82156.
// From https://stackoverflow.com/a/659939/82156
public Page getPage(Integer id) {
Page p = cache.get(id);
if (p == null) {
synchronized (getCacheSyncObject(id)) {
p = getFromDataBase(id);
cache.store(p);
}
}
}
private ConcurrentMap<Integer, Integer> locks = new ConcurrentHashMap<Integer, Integer>();
private Object getCacheSyncObject(final Integer id) {
locks.putIfAbsent(id, id);
return locks.get(id);
}
However, one problem with that implementation is that the hashmap will grow unbounded. Is there a way to remove the hash key when the thread is complete without screwing up the concurrency?