【问题标题】:Using Guava Cache As Map with Time Based Eviction使用 Guava 缓存作为基于时间的驱逐的地图
【发布时间】:2019-10-29 22:40:09
【问题描述】:

我基本上需要一个地图,其中条目将在特定的已知时间段后过期,然后被删除。 它在我的应用程序中的使用方式并不是真正的缓存,但似乎 Guava 缓存可以达到目的。这会是正确的选择吗?一件事是我需要查询地图是否为空,并且我看到 Guava 只有一个 size 函数,其文档说这只是一个近似值。

【问题讨论】:

  • 缓存为空为什么要查询?
  • 它基本上是用作地图的。我有一个Map<String, Cache<String, String>>,一旦特定的Cache 值变为空,我想将它从Map 中删除。
  • 之所以是近似值是因为多个线程可以同时修改缓存。您能否详细说明为什么要从地图中删除空缓存?是为了表演吗?它真的会为您节省很多吗?
  • @LouisWasserman 我需要从地图中清除空缓存的原因是关于应用程序的正确性。

标签: java guava


【解决方案1】:

您可以为此目的使用番石榴。请注意有关清理的警告,如文档 here 中所述(转载如下)。

使用 CacheBuilder 构建的缓存不执行清理和逐出值 “自动”或在值过期后立即,或任何 排序。相反,它在期间执行少量维护 写操作,或者在偶尔的读操作期间,如果写是 很少见。

原因如下:如果我们要执行Cache 持续维护,我们需要创建一个线程,它的 操作将与用户操作竞争共享锁。 此外,一些环境限制线程的创建, 这将使 CacheBuilder 在该环境中无法使用。

相反,我们将选择权交给您。如果您的缓存是 高吞吐量,那么您不必担心执行缓存 维护以清理过期条目等。如果你的缓存 很少写入并且您不希望清理以阻止缓存 读取,您可能希望创建自己的维护线程来调用 定期缓存.cleanUp()。

如果您想为某个缓存安排定期缓存维护, 很少有写入,只需安排维护使用 ScheduledExecutorService。

至于检查大小点,size() 是近似值是正确的。如果您需要在条目无效时执行某些操作,您应该使用removalListener 功能。来自documentation的相关示例代码现转载。

CacheLoader<Key, DatabaseConnection> loader = new CacheLoader<Key, DatabaseConnection> () {
  public DatabaseConnection load(Key key) throws Exception {
    return openConnection(key);
  }
};
RemovalListener<Key, DatabaseConnection> removalListener = new RemovalListener<Key, DatabaseConnection>() {
  public void onRemoval(RemovalNotification<Key, DatabaseConnection> removal) {
    DatabaseConnection conn = removal.getValue();
    conn.close(); // tear down properly
  }
};

return CacheBuilder.newBuilder()
  .expireAfterWrite(2, TimeUnit.MINUTES)
  .removalListener(removalListener)
  .build(loader);

【讨论】:

  • removalListener 如何让我知道缓存是否为空?
  • 为什么需要知道缓存是否为空?我不认为 Guava 可以提供这样的功能,所以如果您出于任何原因需要它,您可能必须自己编写。
  • 不过,理论上你可以维护自己的计数器。将项目添加到缓存时增加它,删除时减少(通过侦听器)。如果它变为 0,则满足您的条件。
  • 计数器很难,因为它很难确定何时应该递增。 put 可能是重复元素。相反,您需要维护密钥集,并在删除通知时从集中删除密钥(在通知中提供)。然后如果集合为空,则缓存为空。考虑一个封装缓存的类(可能扩展 ForwardingCache),公开 get/put 方法,实现 RemovalListener 并跟踪缓存的键以确定空状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-27
  • 1970-01-01
  • 1970-01-01
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多