相关疑难解决方法(0)

可靠地迫使番石榴地图被驱逐

编辑:我重新组织了这个问题,以反映自那以后可用的新信息.

这个问题是基于对Viliam关于Guava Maps使用懒惰驱逐的问题的回答:Guava地图中的驱逐懒惰

请首先阅读这个问题及其回答,但基本上结论是Guava地图不会异步计算并强制执行驱逐.给出以下地图:

ConcurrentMap<String, MyObject> cache = new MapMaker()
        .expireAfterAccess(10, TimeUnit.MINUTES)
        .makeMap();
Run Code Online (Sandbox Code Playgroud)

在访问条目后十分钟过后,在再次"触摸"地图之前,它仍然不会被驱逐.已知的方法可以做到这包括平时的存取- get()put()containsKey().

问题的第一部分[已解决]:其他调用会导致地图被"触摸"?具体来说,有谁知道是否size()属于这一类?

想知道这一点的原因是我已经实现了一个计划任务,偶尔轻推我用于缓存的Guava地图,使用这个简单的方法:

public static void nudgeEviction() {
    cache.containsKey("");
}
Run Code Online (Sandbox Code Playgroud)

但是,我还使用cache.size()以编程方式报告地图中包含的对象数量,以确认此策略是否有效.但我无法看到这些报道的差异,现在我想知道是否size()也会导致驱逐.

答:所以马克指出,在第9版,驱逐仅被调用get(),put()replace()方法,这可以解释为什么我没有看到一个效果containsKey().这显然会随着下一版本的番石榴而改变,该版本即将发布,但不幸的是我的项目发布时间越早.

这让我陷入了一个有趣的困境.通常我仍然可以通过调用来触摸地图get(""),但我实际上正在使用计算地图:

ConcurrentMap<String, MyObject> cache = new MapMaker()
        .expireAfterAccess(10, TimeUnit.MINUTES)
        .makeComputingMap(loadFunction);
Run Code Online (Sandbox Code Playgroud)

其中loadFunction加载MyObject对应于数据库中的关键.它开始看起来像我没有简单的方法强迫驱逐直到r10.但是,即使能够可靠地强制驱逐,我的问题的第二部分仍然存在疑问:

我的问题的第二部分[解决]:在反应的反应之一链接的问题,并触摸地图可靠驱逐所有过期项?在链接的答案中,Niraj Tolia另有说明,称驱逐可能只是分批处理,这意味着可能需要多次调用触摸地图以确保所有过期的对象被驱逐.他没有详细说明,但这似乎与基于并发级别的地图被拆分成相关.假设我使用r10,其中a containsKey("")确实调用驱逐,那么这将是整个地图,还是只针对其中一个段?

答: maaartinus已经解决了这部分问题:

请注意, …

java caching guava

19
推荐指数
3
解决办法
5332
查看次数

从Guava RemovalListener重新插入条目是否安全?

我有一个番石榴Cache(或者说,我从迁移MapMakerCache)和值代表长时间运行的作业.我想将expireAfterAccess行为添加到缓存中,因为这是清理缓存的最佳方法; 但是,即使在一段时间内没有通过缓存访问该作业,该作业仍可能仍在运行,在这种情况下,我需要阻止它从缓存中删除.我有三个问题:

  1. 重新插入在RemovalListener回调期间被删除的缓存条目是否安全?

  2. 如果是这样,它是线程安全的,这样,CacheLoaderRemovalListener回调仍在另一个线程中发生时,没有可能产生该键的第二个值吗?

  3. 有没有更好的方法来实现我想要的?这不是严格/只是一个"缓存" - 每个密钥只使用一个且只有一个值是至关重要的 - 但我也希望在它所代表的工作完成后将条目缓存一段时间.我以前使用MapMaker过,我需要的行为现在在该类中被弃用了.在作业运行时定期ping地图是不优雅的,在我的情况下,不可行.也许正确的解决方案是拥有两个地图,一个没有驱逐,一个有,并在完成时将它们迁移.

我也会提出一个功能请求 - 这可以解决问题:允许锁定单个条目以防止驱逐(然后解锁).

[编辑以添加一些细节]:此地图中的键指的是数据文件.这些值可以是正在运行的写入作业,也可以是已完成的写入作业,或者 - 如果没有正在运行的作业 - 是一个只读,生成在查找对象,其中包含从文件中读取的信息.重要的是每个文件正好有零个或一个条目.我可以为这两件事使用单独的地图,但必须在每个键的基础上进行协调,以确保一次只存在一个或另一个.在获得并发性方面,使用单个映射使其更简单.

java concurrency caching guava

13
推荐指数
1
解决办法
1099
查看次数

如何在Java中实现规范化映射?

我目前正在编写自己的小ORM,并发现自己面临着创建规范化映射的任务,以防止从数据库中多次加载同一个实体.

我目前的做法是使用a HashMap<Object, WeakReference<Object>>.密钥是映射的数据库实体的主键(ArrayList<Object>如果它是复合键),则值为WeakReference<Object>.

我的主要问题是如何清理地图?当一个对象不再使用时,地图中的弱引用将会出现null,我只会在下一次查找时发现这一点(或者,如果我不再查看该对象,则永远不会发现).ReferenceQueue当它们被清除时,我可以使弱引用注册为a ,然后每次查看时检查该队列.清除的引用不会给我任何关于哪个对象被清除的提示,所以我想我必须子类WeakReference将该键存储在地图中,所以我可以在清除引用后将其删除.

这是要走的路,还是有更简单的方法来实现它?

java orm weak-references canonicalization

10
推荐指数
1
解决办法
5404
查看次数

使用软引用有什么"实际后果"?

根据番石榴的文档MapMaker.softValues():

警告:在大多数情况下,最好设置每缓存最大大小而不是使用软引用.如果您熟悉软引用的实际后果,则应该只使用此方法.

我对软引用有一个中间的理解 - 它们的行为,用途以及它们与垃圾收集的契约.但是我想知道这些实际后果是由博士提到的.为什么使用最大尺寸而不是软参考更好?在实现缓存方面,软引用的算法和行为是否使得它们的使用比硬编码上限更有效?

java caching garbage-collection soft-references

6
推荐指数
1
解决办法
775
查看次数