2015-11-07 3 views
0

У меня есть класс кеша, который основан на ConcurrentHashMap. Этот кеш используется для хранения результатов, полученных из относительно медленной службы справочных данных.Кэш для параллельного запроса

Одна из проблем заключается в том, что, когда несколько потоков пытаются получить ключ, который не существует, оба потока будут отправляться и извлекать один и тот же ключ из справочной службы данных, что приводит к двум вызовам справочных данных.

Я собираюсь улучшить реализацию кэша, чтобы только один из потоков запрашивал службу справочных данных.

Есть ли стандартная реализация для этого?

+0

google 'memoizer ConcurrentHashMap' – ZhongYu

+0

Есть небольшие кэши, такие как Goggle Guava cache или [cache2k] (http://cache2k.org), которые по умолчанию имеют желаемое поведение. В Guava вам нужно сделать LoadCache, в cache2k вам нужно определить источник кеша. – cruftex

ответ

0

Вот пример код, который хранит уникальные ключи в списке <> замков и если объект с эквивалентной стоимостью передается он будет возвращать один и тот же ключ для него, а затем synchroized блока на ключе

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; 
     } 
     } 
    } 
+0

Вы предполагаете, что они обращаются к одному и тому же фактическому ключу. Что делать, если они имеют доступ с двумя равными ключами? – RealSkeptic

+0

Да, это проблематично, я обновлю сообщение. – Zpetkov

Смежные вопросы