我List<CompletableFuture>
存储了Map
private final Map<UUID, List<CompletableFuture>> hydrationProcesses = new ConcurrentHashMap<>();
目前有一个守护程序线程每隔30秒运行一次,并删除已经完成的所有Futures
。
有很多TTL失效实现,我正在寻找基于某些谓词的失效。我想摆脱这个守护程序线程。
是否存在基于某些自定义逻辑的计划缓存失效的开箱即用解决方案。也许我错过了Spring / Guava中的某些东西?
也许与Guava的相似之处
CacheBuilder.newBuilder()
.expireAfterAccess(2,TimeUnit.MILLISECONDS)
.build(loader);
而是在访问后将所有内容标记为已过期我需要检查此Future是否已经完成,然后将其从缓存中删除。
答案 0 :(得分:1)
我怀疑有基于番石榴的解决方案。由于您没有特别要求“仅限番石榴”的解决方案,因此我想了解如何使用cache2k来解决问题。
以下是设置的外观:
final long RECHECK_INTERVAL_MILLIS = 30000;
Cache<UUID, CompletableFuture<Void>> cache =
new Cache2kBuilder<UUID, CompletableFuture<Void>>(){}
.loader(new AdvancedCacheLoader<UUID, CompletableFuture<Void>>() {
@Override
public CompletableFuture<Void> load(UUID key,
long currentTime,
CacheEntry<UUID, CompletableFuture<Void>> currentEntry) {
return currentEntry != null ? currentEntry.getValue() : null;
}
})
.expiryPolicy(new ExpiryPolicy<UUID, CompletableFuture<Void>>() {
@Override
public long calculateExpiryTime(UUID key,
CompletableFuture<Void> value,
long loadTime,
CacheEntry<UUID, CompletableFuture<Void>> oldEntry) {
return value.isDone() ? NOW : loadTime + RECHECK_INTERVAL_MILLIS;
}
})
.refreshAhead(true)
.build();
实际上,cache2k具有与Guava或其他缓存类似的功能。然而,有一些微小的扩展,允许更复杂的设置。
这里使用的技巧是在读取操作中配置缓存,但使加载器返回当前缓存值。当条目到期时,由于refreshAhead(true)
而调用加载器,但保留当前值并再次评估到期策略。您希望检查的谓词将进入到期政策。
其他缓存也已经过读取和自定义过期,但缺少“智能加载器”(AdvancedCacheLoader
)的概念,它可以根据现有缓存值更有效地运行。
我们在制作中使用与此相似的设置。
也存在不利因素。如果使用自定义过期,则cache2k每个缓存使用一个计时线程。这意味着你的额外线程不会消失。将来会增强cache2k,以便在所有缓存之间共享一组全局时序线程。
免责声明:我是cache2k的作者,所以我绝对不能确定没有基于番石榴的可能解决方案。