java - Guava CacheBuilder 在缓存到期后不会立即调用removingListener
问题描述
从我的应用程序日志中,我觉得在缓存键过期后不会立即调用 removeListener 。这在以下场景中产生了问题
缓存配置:
SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
GuavaCache cache = new GuavaCache("cacheData", CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).removalListener(expiredCacheListener()).build());
在应用程序逻辑中,我看到当cache.get(key)
被调用时,如果没有值(因为缓存由于expireAfterAccess()
方法时间限制而过期),那么它会在缓存中为同一个键放置一个新值,因为旧键已过期/删除。
在这个写操作之后,我认为removingListener正在调用expiredCacheListener()
具有更改过期键值逻辑的方法.... //但这实际上是在更改新值!!!
现在我在缓存中有一个值不正确的有效键
如果一个线程能够使密钥过期,那么同一个线程不应该立即调用removingListener吗?我该如何解决这个问题?
解决方案
这就是 Guava Cache 的工作原理,请参阅CachesExplained:
什么时候进行清理?
构建的缓存
CacheBuilder
不会“自动”或在值过期后立即执行清理和逐出值,或任何类似的操作。相反,它在写入操作期间执行少量维护,或者如果写入很少,则在偶尔的读取操作期间执行。
阅读更多内容,了解番石榴的创造者“把选择权交给你”;您可以自行维护清理线程。
对于更高级的Cache
用例,请使用Caffeine,它“使用受 Google Guava 启发的 API 提供内存缓存”。删除wiki 页面提到,对于同步删除侦听器,您可以使用CacheWriter
.