Java 用于并发查询的缓存

Java 用于并发查询的缓存,java,caching,concurrency,Java,Caching,Concurrency,我有一个基于ConcurrentHashMap的缓存类。这个缓存用于存储我从相对较慢的引用数据服务中获得的结果 这其中的一个问题是,当多个线程试图获取一个不存在的密钥时,两个线程都会从引用数据服务获取相同的密钥,从而导致两个引用数据调用 我正在考虑改进缓存的实现,以便只有一个线程查询引用数据服务 有没有标准的实现方法?这里有一个示例代码,它将唯一的键存储在一个列表keyLocks中,如果传递了一个具有等效值的对象,它将为该对象返回相同的键,然后在该键上返回一个同步化块 private final

我有一个基于ConcurrentHashMap的缓存类。这个缓存用于存储我从相对较慢的引用数据服务中获得的结果

这其中的一个问题是,当多个线程试图获取一个不存在的密钥时,两个线程都会从引用数据服务获取相同的密钥,从而导致两个引用数据调用

我正在考虑改进缓存的实现,以便只有一个线程查询引用数据服务


有没有标准的实现方法?

这里有一个示例代码,它将唯一的键存储在一个列表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(键、结果);
返回结果;
}
}
}

您假设他们使用相同的实际密钥访问。如果他们使用两个相等的键进行访问怎么办?google
memoizer ConcurrentHashMap
有轻量级缓存,比如Goggle Guava cache或,默认情况下具有所需的行为。在Guava中,您需要进行加载缓存,在cache2k中,您需要定义缓存源。