如果您使用的是expireAfterWrite
,那么您可以按时间戳顺序获取条目的快照。由于这个调用需要获取驱逐锁,它提供了一个不可变的快照而不是一个迭代器。这很混乱,例如,您必须提供一个可能不正确的限制,并且取决于到期时间。
Duration maxAge = Duration.ofMinutes(1);
cache.policy().expireAfterWrite().ifPresent(policy -> {
Map<K, V> oldest = policy.oldest(1_000);
for (K key : oldest.keySet()) {
// Remove everything written more than 1 minute ago
policy.ageOf(key)
.filter(duration -> duration.compareTo(maxAge) > 0)
.ifPresent(duration -> cache.invalidate(key));
}
});
如果您自己维护时间戳,则可以使用cache.asMap()
视图进行无序迭代。这可能是最简单和快速的。
long cutoff = ...
var keys = cache.asMap().entrySet().stream()
.filter(entry -> entry.getValue().timestamp() < cutoff)
.collect(toList());
cache.invalidateAll(keys);
一种行不通但值得一提来解释原因的方法是变量过期,expireAfter(expiry)
. 您可以根据之前的设置为每次读取设置新的持续时间。这在条目返回给调用者后生效,因此虽然您可以立即过期,但它会K1
(至少)服务一次。
否则,您可以在缓存之外的检索时间进行验证,并依靠大小驱逐。这种方法的缺陷是它确实会污染缓存将死条目。
V value = cache.get(key);
if (value.timestamp() < cutoff) {
cache.asMap().remove(key, value);
return cache.get(key); // load a new value
}
return value;
或者你可以维护你自己的写顺序队列等。所有这些都会让你得到更多的混乱。对于您的情况,完整的迭代可能是最简单且最不容易出错的方法。