从我的应用程序日志中,我觉得在缓存键过期后没有立即调用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/