在遍历番石榴缓存条目时使条目无效
Invalidating an entry while iterating over guava cache entries
我正在使用番石榴缓存,我有一个用例,我需要迭代缓存条目并在它们满足特定要求时使它们无效。代码如下所示:
Cache<String, String> cache = CacheBuilder.newBuilder()
.expireAfterWrite(30, TimeUnit.MINUTES)
.build();
for (String s : cache.asMap().keySet()) {
if (someCalculation(s)) {
cache.invalidate(s);
}
}
在 运行 上述代码之后,我没有看到缓存条目有任何不一致。我问这个问题是为了看看这是否总能给我一致的结果,以及是否有更好的方法来解决我的用例。
我认为你的方法不对。 asMap documentation 表示:
Iterators from the returned map are at least weakly consistent: they
are safe for concurrent use, but if the cache is modified (including
by eviction) after the iterator is created, it is undefined which of
the changes (if any) will be reflected in that iterator.
这与您正在做的事情相关,因为您在失效时进行迭代,所以在缓存失效后您的迭代器(隐含在 for 循环中)会发生什么是不确定的。
我会使用以下事实(再次来自文档):
Modifications made to the map directly affect the cache.
修改地图的一个巧妙方法是修改它的键集(Java API 文档说“该集由地图支持,因此对地图的更改反映在设置,反之亦然。")
我会这样做:
Cache<String, String> cache = CacheBuilder.newBuilder()
.expireAfterWrite(30, TimeUnit.MINUTES)
.build();
cache.asMap().keySet().removeIf(s -> someCalculation(s));
我正在使用番石榴缓存,我有一个用例,我需要迭代缓存条目并在它们满足特定要求时使它们无效。代码如下所示:
Cache<String, String> cache = CacheBuilder.newBuilder()
.expireAfterWrite(30, TimeUnit.MINUTES)
.build();
for (String s : cache.asMap().keySet()) {
if (someCalculation(s)) {
cache.invalidate(s);
}
}
在 运行 上述代码之后,我没有看到缓存条目有任何不一致。我问这个问题是为了看看这是否总能给我一致的结果,以及是否有更好的方法来解决我的用例。
我认为你的方法不对。 asMap documentation 表示:
Iterators from the returned map are at least weakly consistent: they are safe for concurrent use, but if the cache is modified (including by eviction) after the iterator is created, it is undefined which of the changes (if any) will be reflected in that iterator.
这与您正在做的事情相关,因为您在失效时进行迭代,所以在缓存失效后您的迭代器(隐含在 for 循环中)会发生什么是不确定的。
我会使用以下事实(再次来自文档):
Modifications made to the map directly affect the cache.
修改地图的一个巧妙方法是修改它的键集(Java API 文档说“该集由地图支持,因此对地图的更改反映在设置,反之亦然。")
我会这样做:
Cache<String, String> cache = CacheBuilder.newBuilder()
.expireAfterWrite(30, TimeUnit.MINUTES)
.build();
cache.asMap().keySet().removeIf(s -> someCalculation(s));