我需要确保多个线程不会同时尝试访问同一个资源。我有一堆这些资源,所以我想为每个资源(而不是一个全局锁)拥有一个单独的锁对象,这样线程就不会不必要地阻塞彼此。
ConcurrentMap.putIfAbsent()
Eddie在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);
}
但是,该实现的一个问题是哈希图将无限增长。有没有办法在线程完成时删除哈希键而不会搞砸并发?