从我的应用程序日志中,我感觉在缓存键过期后没有立即调用removeListener。在以下情况下这会造成问题
缓存配置:
SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
GuavaCache cache = new GuavaCache("cacheData", CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).removalListener(expiredCacheListener()).build());
在应用程序逻辑中,我看到当调用cache.get(key)
时,如果没有任何值(因为由于expireAfterAccess()
方法的时间限制,缓存已过期),则会在其中放入一个新值由于旧密钥已过期/已删除,因此相同密钥的缓存。
在执行此写操作之后,立即,我认为removeListener正在调用expiredCacheListener()
方法,该方法具有更改过期密钥的值的逻辑。...//但这实际上是在更改新值!!!
现在我在缓存中有一个有效的密钥且值不正确
如果一个线程能够使密钥失效,那么同一个线程是否应该立即调用removeListener?我该怎么解决?
答案 0 :(得分:2)
这就是Guava缓存的工作方式,请参见CachesExplained:
什么时候进行清理?
使用
CacheBuilder
构建的缓存不执行清除和逐出值 “自动”或值过期后立即进行,或 排序。相反,它会在执行期间进行少量维护 写操作,或者在偶尔的读操作期间(如果写) 稀有。
了解更多信息,了解Guava的创建者将“选择权掌握在您的手中”,您就可以自由维护自己的线索线程。
对于更高级的Cache
用例,请使用Caffeine,它“使用Google Guava启发的API提供内存中的缓存”。 Removal维基页面提到,对于同步删除侦听器,您可以使用CacheWriter
。