Google Guava的CacheLoader loadAll()方法实现问题

Ana*_*hvi 3 java guava

我有兴趣知道google guava 11.0库中引入的loadAll方法实现的有效方法是什么.

下面的代码描述
了根据CachesExplained中的示例加载所有扩展的方法实现

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder().maximumSize(1000)
.refreshAfterWrite(1, TimeUnit.MINUTES)
.build(
   new CacheLoader<Key, Graph>() {
     public Graph load(Key key) { // no checked exception
       return getGraphFromDatabase(key);
     }

     public Map<Key, Graph> loadAll(Iterable<? extends K> keys) {
         return getAllGraphsFromDatabase(keys);
     }
   }
);

private Map<Key, Graph> getAllGraphsFromDatabase(Iterable<? extends key> keys)
{
  lListOfGraph = //resultset got from DB Call
  for (lCount = 0; lCount < lListOfGraph.size(); lCount++)
  {
     lGraph = (Graph)lListOfGraph.get(lCount).get(0);
     graphs.asMap().put((key , lGraph);
  }
  return (Map<key, Graph>) graphs;
}
Run Code Online (Sandbox Code Playgroud)

这里返回的类型是Map throws error java.lang.ClassCastException:com.google.common.cache.LocalCache $ LocalLoadingCache不能转换为java.util.Map(知道加载Cache对象不能是Map类型的事实)

如果这不是使用LoadingCache的正确实现方式,那么如何在LoadingCache的Component中注入数据,以便它可以用作Cache.

Sim*_*onC 5

您的getAllGraphsFromDatabase方法应该从底层数据存储中获取值.在LoadingCache实现处理将返回值的地图给你.

我认为你的加载方法应如下所示:

private Map<Key, Graph> getAllGraphsFromDatabase(Iterable<? extends key> keys)
{
  final List<Graph> lListOfGraph = //resultset got from DB Call

  final Map<Key, Graph> map = new HashMap<Key, Graph>(listOfGraph.size());
  for (final Graph graph : lListOfGraph)
    map.put(graph.getKey(), graph);

  return map;
}
Run Code Online (Sandbox Code Playgroud)

  • 你不应该直接把任何东西放到地图上.`CacheLoader`的要点是检索要放入地图的`LoadingCache`的值.因此,如果从DB中检索到`lListOfGraph`,则需要将其作为地图返回. (2认同)
  • "CacheLoader.load"和"CacheLoader.loadAll"只会被调用不在缓存中的密钥(因为它们之前没有加载过,或者因为它们已经过期).所以说你在调用`getAll(1,2,3)`之前调用`get(1)`,``loadAll`方法只用`(2,3)`调用.因此,您的缓存将具有键"1","2"和"3"的单个"Graph"条目.另外,作为参考,`LoadingCache`确保同时为两个不同的线程同时调用`load` /`loadAll`方法两次. (2认同)
  • 在`loadAll`实现中临时创建的`Map`几乎会立即被垃圾收集.除非你实际上有基准指示,否则这几乎肯定不会成为性能瓶颈. (2认同)