여러 스레드가 같은 리소스에 동시에 액세스하지 못하게해야합니다. 나는 이러한 리소스를 가지고 있으므로 스레드가 불필요하게 서로를 블로킹하지 않도록 각 리소스 (하나의 전역 잠금보다는)에 대해 별도의 잠금 객체를 갖고 싶습니다.제거와 함께 ID 동기화하기
에디는 ConcurrentMap.putIfAbsent()
을 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);
}
그러나이 구현의 한 가지 문제점은 해시 맵이 무제한으로 확장된다는 것입니다. 스레드가 동시성을 망치지 않고 완료되면 해시 키를 제거하는 방법이 있습니까?
'locks.remove (id, id)'의 문제점은 무엇입니까? – OldCurmudgeon
잠금 맵은 실제 캐시보다 작습니다. 캐시를 정리할 수있는 메커니즘이 있습니까? 그렇다면 잠금 맵도 정리해야합니다. – flup