Car*_*oti 3 java caching guava
我对番石榴缓存有一种奇怪的行为(至少对我而言).第一次点击后,以下访问将返回一个空对象.我没有使用奇怪的证据,所以我无法弄清楚我做错了什么.我声明了以下LoadingCache:
LoadingCache<String, Vector<Location>> locations = CacheBuilder.newBuilder()
.maximumSize(100000)
.build(
new CacheLoader<String,Vector<Location>>() {
@Override
public Vector<Location> load(String key) {
return _getLocationListByTranscriptId(key);
}
});
Run Code Online (Sandbox Code Playgroud)
我只在这种方法中使用它:
public Vector<Location> getLocationListByTranscriptId (String transcriptid) {
if (transcriptid.equals("TCONS_00000046")) System.out.println("tcons found, will this work?");
Vector<Location> result;
try {
result = locations.get(transcriptid);
} catch (ExecutionException e) {
System.err.println("Error accessing cache, doing the hard way");
result = _getLocationListByTranscriptId(transcriptid);
}
if (transcriptid.equals("TCONS_00000046")){
if (result.size()==0){
System.out.println("this is a problem");
return null;
}
System.out.println("this is good!");
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
迭代输入字符串的集合,我得到以下输出:
tcons found, will this work?
this is good!
tcons found, will this work?
this is a problem
Run Code Online (Sandbox Code Playgroud)
因此,第一次使用缓存时,它可以工作,但A)未正确存储该值以供将来访问; B)为某些奇怪的行为重置该值.我能做什么?谢谢大家阅读本文!
编辑:感谢axtavt回答我可以立即弄清楚我在哪里编辑结果列表.不知道为什么,我确信guava缓存返回值的副本.感谢您的回答,以及有关防御性编程的建议.(对不起,如果我还不能评价你的答案).
我相信你意外地清除Vector代码中的某个地方.有两种可能性:
Vector 由从缓存中获取它的代码修改.
通过制作防御性副本(虽然它破坏了缓存的想法)或返回集合的不可变视图,可以防止这种错误:
LoadingCache<String, List<Location>> locations = CacheBuilder.newBuilder()
.maximumSize(100000)
.build(
new CacheLoader<String, List<Location>>() {
@Override
public List<Location> load(String key) {
return Collections.unmodifiableList(
_getLocationListByTranscriptId(key));
}
});
Run Code Online (Sandbox Code Playgroud)
以这种方式更改代码后,很容易发现非法修改收集的地方.
请注意,没有不可修改的视图Vector,因此List应该使用.
_getLocationListByTranscriptId()将其结果存储在一个字段中,可以通过其他方法(或其他相同方法的调用)访问该字段.因此,您应该检查_getLocationListByTranscriptId()是否在字段中留下对其结果的任何引用.
| 归档时间: |
|
| 查看次数: |
898 次 |
| 最近记录: |