当前位置: 首页 > 面试题库 >

我理想的使用番石榴缓存

田阳泽
2023-03-14
问题内容

在过去的几周内,我一直在尝试使用番石榴的MapMaker查找理想的缓存实现。

根据我所学的知识,我的下一个尝试将弃用软值,以使用maximumSize和expireAfterAccess:

ConcurrentMap<String, MyObject> cache = new MapMaker()
        .maximumSize(MAXIMUM_SIZE)
        .expireAfterAccess(MINUTES_TO_EXPIRY, TimeUnit.MINUTES)
        .makeComputingMap(loadFunction);

哪里

Function<String, MyObject> loadFunction = new Function<String, MyObject>() {
   @Override
   public MyObject apply(String uidKey) {
      return getFromDataBase(uidKey);
   }
};

但是,我仍然要解决的一个问题是,一旦它们用完了,即使对象很容易到达,此实现也将逐出对象。这可能会导致环境中漂浮着具有相同UID的多个对象,而这是我所不希望的(我相信我试图实现的目标称为规范化)。

据我所知,唯一的答案是要有一个附加的映射,它可以作为一个内部映射器,可以检查数据对象是否仍在内存中:

ConcurrentMap<String, MyObject> interner = new MapMaker()
        .weakValues()
        .makeMap();

负载函数将被修改:

Function<String, MyObject> loadFunction = new Function<String, MyObject>() {
   @Override
   public MyObject apply(String uidKey) {
      MyObject dataObject = interner.get(uidKey);
      if (dataObject == null) {
         dataObject = getFromDataBase(uidKey);
         interner.put(uidKey, dataObject);
      }
      return dataObject;
   }
};

但是,对于缓存使用两个映射而不是一个映射似乎效率低下。有没有更复杂的方法来解决这个问题?总的来说,我应该采用正确的方式还是应该重新考虑缓存策略?


问题答案:

两张地图是否有效完全取决于getFromDatabase()的价格以及对象的大小。这样做似乎并非超出所有合理范围。

至于实现,看起来您可能可以以稍微不同的方式对地图进行分层以获得所需的行为,并且仍然具有良好的并发属性。

  1. 创建具有弱值的第一个地图,然后将计算函数getFromDatabase()放在此地图上。
  2. 第二个地图是即将到期的地图,也正在计算,但是此功能仅从第一个地图获得。

通过第二张地图进行所有访问。

换句话说,到期映射的作用是将对象中最近使用的子集固定在内存中,而弱引用映射是真正的缓存。

-dg



 类似资料:
  • 问题内容: 我在commons- lang中使用了简单的DTO。现在,我尝试使用Google Guava代替Apache Commons库。我在番石榴找到了。但是如果班上有很多成员,这太冗长了。例如: 如果我使用commons-lang,则简单得多: 有什么更好的方法可以用Guava而不是commons-lang 来实现? 番石榴文件 问题答案: 我有番石榴的小招。我将 IntelliJ IDEA

  • 问题内容: 刚刚发现了Guava库项目。 这些与GWT兼容吗? 问题答案: 从该页面的介绍性PDF中, 您可以在…上使用这些库。 在JDK 6上 在Android上, 我们认为。需要志愿者来帮助我们进行测试。 在Google App Engine上, 我们认为。需要志愿者来帮助我们进行测试。 在GWT上-参差不齐! 由于GWT的JDK库支持 可能参差不齐,也许是2/3,所以到目前为止,这些库中的东

  • 问题内容: 我想知道哪个更有效,为什么? 1) 要么 2) 问题答案: 我看不出您为什么要在此处使用builder的任何原因: 比在这种情况下制作一个更具可读性, 不会推断通用类型,并且在用作单行代码时必须自己指定类型, (来自docs) 在与另一个不可变集合调用时 做得很好( 尝试避免在安全的情况下实际复制数据 ), (从源) 调用以前创建的,同时避免为零元素和一元素集合创建任何列表(分别返回空

  • 我想为番石榴设个坑(http://pitest.org/)进行突变熟练度测试,但我在尝试运行时出现以下错误。这是我得到的错误: 基本上,要么PIT没有检测到测试,要么测试在PIT中运行不正常,所有测试都失败了。我读了这篇文章:JUnit测试通过,但PIT说套件不是绿色的,我认为“您的代码库是否包含可变静态状态?(例如在单例中)”是问题所在,但我不知道如何修复它。如果测试套件有一些隐藏的顺序依赖关系

  • 我的 Spark 版本是 2.2.0,它在本地工作,但在具有相同版本的 EMR 上,它给出了以下异常。

  • 我对番石榴很陌生(说实话,我不是“很新”,我是这个主题的新手),所以我决定浏览一些文档,在阅读本文时感到非常惊讶: 我不明白这个方法的意义。这意味着,与其这样做,不如: (如果myObject为null,这可能会导致) 我应该用 如果为空,这将抛出一个,如果它不是空,则返回。 我很困惑,这可能是有史以来最愚蠢的问题,但是... 这有什么意义?这两条线和我能想到的任何情况下的结果是完全一样的。 我甚