我需要为类slowResult()
的实例获取慢速方法Something
的结果。单独缓存并没有帮助,因为实例几乎不会重复。幸运的是,我知道结果实际上只取决于一些容易获得的Attributes
Something
,所以我可以在代码中使用Map<Attributes, Result>
作为缓存
Result fastResult(Something something) {
final Attributes attributes = attributesFor(something)
Result result = cache.get(attributes);
if (result!=null) return result;
result = something.slowResult();
cache.put(attributes, result);
return result;
}
为了保持缓存有限,我使用了现已弃用的方法maximumSize
和expireAfterAccess
。弃用是因为要使用新的类CacheBuilder
。但是,我发现如何将它应用到我的案例中的方法并不好。缓存键需要是Attributes
的实例,但在缓存加载中需要Something
的实例,并且没有简单的方法可以从Attributes
重新创建它。
这个问题有好的解决方案吗?
答案 0 :(得分:3)
非常有趣!我认为我们没有听说过这样的案例。
对于11.0,您将能够cache.asMap().put()
,因此暂时忽略弃用警告可能是可以的。我们正在考虑可能在10.1补丁版本中启用它,因为几个用户似乎在类似的船上。
但是,在11.0中,我们正在努力的另一个想法是允许你这样做:
Result fastResult(final Something something) {
return cache.get(
attributesFor(something),
new Callable<Result>() {
public Result call() {
return something.slowResult();
}
});
}
答案 1 :(得分:0)
您可以直接关闭Cache of Something吗?
答案 2 :(得分:0)
好吧,说明这个问题的一种方法是,“我如何比较Attributes.equals()
缓存,但仍然可以访问Something
来创建值”。所以,我认为这可能有用......
class SomethingKey {
private Something something;
private final Attributes attributes;
SomethingKey(Something s) {
this.something = s;
this.attributes = attributesFor(something);
}
public Result createResult() {
Something something = this.s;
this.s = null;
return something.slowResult();
}
public boolean equals(Object o) {
if(o==this) return true;
if(o==null || o.getClass() != this.getClass) return false;
SomethingKey that = (SomethingKey)o;
return this.attributes.equals(that.attributes);
}
}
然后CacheLoader.load
基本上是
Result load(SomethingKey k) {
return k.createResult();
}
地图将是
Cache<SomethingKey,Result> map = ...;
当然,缺点是你要为每个请求创建一个新的SomethingKey,但是......