java - Guava CacheBuilder 在缓存过期后不会立即调用removalListener

标签 java caching guava

从我的应用程序日志中,我觉得在缓存键过期后没有立即调用removeListener。这会在下面的场景中产生问题

缓存配置:

SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
GuavaCache cache = new GuavaCache("cacheData", CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).removalListener(expiredCacheListener()).build());

在应用程序逻辑中,我看到当调用cache.get(key)时,如果没有值(因为缓存因expireAfterAccess()而过期) code> 方法时间限制),然后由于旧 key 已过期/已删除,它会在缓存中为同一 key 放置一个新值。

在这个写入操作之后,我认为removalListener正在调用expiredCacheListener()方法,该方法具有更改过期键的值的逻辑....//但是这是实际上改变了新值!!!

现在我有一个有效的 key ,但缓存中的值不正确

如果一个线程能够使 key 过期,那么同一个线程不应该立即调用removeListener吗?我该如何解决这个问题?

最佳答案

这就是 Guava Cache 的工作原理,请参阅 CachesExplained :

When Does Cleanup Happen?

Caches built with CacheBuilder do not perform cleanup and evict values "automatically," or instantly after a value expires, or anything of the sort. Instead, it performs small amounts of maintenance during write operations, or during occasional read operations if writes are rare.

阅读更多内容即可了解 Guava 创作者“将选择权交到您手中”;您可以自行维护清理线程。

对于更高级的缓存用例,请使用Caffeine ,它“使用受 Google Guava 启发的 API 提供内存缓存。” Removal wiki 页面提到,对于同步删除监听器,您可以使用 CacheWriter .

关于java - Guava CacheBuilder 在缓存过期后不会立即调用removalListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54356072/

相关文章:

java - 当所有@OneToMany都是cascade=ALL时,org.hibernate.TransientObjectException

java - transient 变量有什么用?

Java程序以10^-6精度确定嵌套根式常量的值

mysql - 什么是最积极的 FLUSH/RESET mysql 命令来清除查询缓存(以及其他任何...)

javascript - 使用 AngularJs 进行缓存

java - 为什么 Guava 的 MapMaker 在使用弱键时报告我的 map 大小不正确?

java - 在解析本地化数字期间,当错误输入不会导致 ParseException 时,如何处理这种情况?

java - Libgdx 平铺 map 无法正确显示

c++ - 调试 CPU 缓存

java - 键值对的排序