Java 用于并发查询的缓存
我有一个基于ConcurrentHashMap的缓存类。这个缓存用于存储我从相对较慢的引用数据服务中获得的结果 这其中的一个问题是,当多个线程试图获取一个不存在的密钥时,两个线程都会从引用数据服务获取相同的密钥,从而导致两个引用数据调用 我正在考虑改进缓存的实现,以便只有一个线程查询引用数据服务Java 用于并发查询的缓存,java,caching,concurrency,Java,Caching,Concurrency,我有一个基于ConcurrentHashMap的缓存类。这个缓存用于存储我从相对较慢的引用数据服务中获得的结果 这其中的一个问题是,当多个线程试图获取一个不存在的密钥时,两个线程都会从引用数据服务获取相同的密钥,从而导致两个引用数据调用 我正在考虑改进缓存的实现,以便只有一个线程查询引用数据服务 有没有标准的实现方法?这里有一个示例代码,它将唯一的键存储在一个列表keyLocks中,如果传递了一个具有等效值的对象,它将为该对象返回相同的键,然后在该键上返回一个同步化块 private final
有没有标准的实现方法?这里有一个示例代码,它将唯一的键存储在一个列表keyLocks中,如果传递了一个具有等效值的对象,它将为该对象返回相同的键,然后在该键上返回一个同步化块
private final List<Object> keyLocks = new ArrayList<>(); // field in Cache
public Object get(Object key){
Object lock;
synchronized (keyLocks) {
if (!keyLocks.contains(key)) {
keyLocks.add(key);
lock = key;
} else {
lock = keyLocks.get(keyLocks.indexOf(key));
}
}
synchronized (lock) {
if(innerCache.containsKey(key)){
return cache.get(key);
}else{
Object result = dataService.get(key);
innerCache.put(key,result);
return result;
}
}
}
private final List keyLocks=new ArrayList();//缓存中的字段
公共对象获取(对象密钥){
对象锁;
同步(钥匙锁){
如果(!keyLocks.contains(key)){
钥匙锁。添加(钥匙);
锁=钥匙;
}否则{
lock=keyLocks.get(keyLocks.indexOf(key));
}
}
已同步(锁定){
if(innerCache.containsKey(键)){
返回cache.get(key);
}否则{
对象结果=dataService.get(key);
innerCache.put(键、结果);
返回结果;
}
}
}
您假设他们使用相同的实际密钥访问。如果他们使用两个相等的键进行访问怎么办?googlememoizer ConcurrentHashMap
有轻量级缓存,比如Goggle Guava cache或,默认情况下具有所需的行为。在Guava中,您需要进行加载缓存,在cache2k中,您需要定义缓存源。