【问题标题】:invalidate refreshed entry in Guava CacheLoader使 Guava CacheLoader 中的刷新条目无效
【发布时间】:2014-05-01 19:15:10
【问题描述】:

我有一个带有CacheLoader 的番石榴缓存。我在线程中跟踪了一个外部条件,如果发生这种情况,我想异步地 refresh() 所有条目。出于这个原因,我不使用invalidateAll(),因为下一个get() 必须等待加载成功。

相反,我遍历缓存中包含的键和 refresh(k) 所有键,因为我找不到 refreshAll() 方法。这是代码(但与问题无关):

    Set<ResourceLoaderKey> keys = resourceLoaderCache.asMap().keySet();
    for(ResourceLoaderKey k : keys)
    {
        resourceLoaderCache.refresh(k);
    }

我现在的问题是,CacheLoader 中的reload() 可能会检测到资源实际上不再可用。目前reload() 会引发适用于get() 情况的ResourceNotFound 异常。但它不适用于refresh() 的情况,因为只要reload() 失败,就会提供旧值。

我现在可以在加载/重新加载方法中捕获未找到的异常并以某种方式使条目无效,但我想知道是否有官方方法可以做到这一点(返回 null 或 null 未来被记录为警告并被忽略)?能够删除键/缺失值而不是保留占位符对象会很好。

【问题讨论】:

  • 这里有类似的问题,我目前的解决方案很丑,希望有一种支持的方式来做到这一点

标签: java caching guava


【解决方案1】:

guava r17 中目前不存在支持此操作的方法。

您是否尝试过获取所有密钥,然后将所有密钥无效,然后尝试获取您保存的所有密钥?

Set<ResourceLoaderKey> keys = resourceLoaderCache.asMap().keySet();
resourceLoaderCache.invalidateAll(keys);
for(ResourceLoaderKey k : keys) {
    resourceLoaderCache.get(k);        //or getUnchecked() whichever you prefer
}

这应该确保没有陈旧的值留在缓存中,并重新缓存所有存在的值。

(我的问题略有不同,我不得不改变我的假设来解决我的问题)

【讨论】:

  • 我不能这样做,因为我不希望定期更新未更改的键来命中缓存加载器。也许我应该考虑从加载器中调用 invalidate ...
  • @eckes 在刷新所有条目时你不会点击缓存加载器吗?您的 load() 和 reload() 实现有何不同?
  • @eckes 哈哈,这比我想象的更类似于我的问题,我最终手动编写了异步重新加载逻辑,以便我可以处理 NotFoundExceptions 并调用 .invalidate() 否则我会调用.put() 并手动写入缓存条目(这是在缓存加载器之外,idk 适合您的包)
猜你喜欢
  • 1970-01-01
  • 2013-07-13
  • 2017-04-20
  • 1970-01-01
  • 1970-01-01
  • 2017-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多