Java 番石榴缓存:取消特定缓存值的逐出
嘿嘿, 目前正在使用guava缓存用户。因此,我的问题是,如果缓存对象具有特定的属性值,那么guava是否可以重新限制逐出条目。例如,如果user.isOnline()返回true,则即使用户在特定时间段内未被访问(.expireAfterAccess(KEEP_LOADED,TimeUnit.SECONDS)),也不会将其逐出 编辑: 我在CacheBuilder.weighter(…)的javadoc中找到了这个: 当条目的权重为零时,将不考虑基于大小的逐出(尽管仍可以通过其他方式逐出) 但如果我的用户在线,我不想以任何方式驱逐他 基本上,我以这种方式缓存用户:Java 番石榴缓存:取消特定缓存值的逐出,java,caching,guava,Java,Caching,Guava,嘿嘿, 目前正在使用guava缓存用户。因此,我的问题是,如果缓存对象具有特定的属性值,那么guava是否可以重新限制逐出条目。例如,如果user.isOnline()返回true,则即使用户在特定时间段内未被访问(.expireAfterAccess(KEEP_LOADED,TimeUnit.SECONDS)),也不会将其逐出 编辑: 我在CacheBuilder.weighter(…)的javadoc中找到了这个: 当条目的权重为零时,将不考虑基于大小的逐出(尽管仍可以通过其他方式逐出) 但
this.cache = CacheBuilder.newBuilder()
.maximumSize(MAX_CACHED_USERS)
.expireAfterAccess(KEEP_LOADED, TimeUnit.SECONDS)
.build(new UserLoader(core));
编辑:
好的,我可以使用权重器来限制缓存的大小。对于每个在线用户,我可以返回0,对于其他用户,我可以返回1。这将导致缓存保留在线用户。但是如果使用maximumSize和expireAfterAccess会更好。但是CacheBuilder.weighter(…)不会阻止expireAfterAccess(…)设置来驱逐旧用户
编辑:
也许可以以某种方式取消驱逐,但我不确定如何:/
与以下内容相关:
Max您链接到的问题直接描述了如何处理此模式 我会用一张地图和一个缓存。对仍在进行的作业使用映射,或者使用缓存的RemovalListener从映射中删除条目 简单地说,如果有您不想被逐出的数据,它就不属于逐出数据结构 对于您的用例,您需要维护登录用户的映射和最近登录用户的缓存。当用户登录时,它们存储在标准地图中。当他们注销时,他们的对象被移动到缓存中,缓存最终会将他们逐出 您可以(也应该)将此行为隐藏在同时包含贴图和缓存的对象中。这可能看起来像:
public class UserStore {
private final ConcurrentHashMap<Key, User> loggedIn;
private final LoadingCache<Key, User> recentlyAccessed;
...
public User getUser(Key userKey) {
User user = loggedIn.get(userKey);
if (user != null) {
return user;
}
return recentlyAccessed.getUnchecked(userKey); // or .get() if necessary
}
}
公共类用户存储{
私有最终ConcurrentHashMap loggedIn;
私有最终加载缓存最近访问;
...
公共用户getUser(Key userKey){
User=loggedIn.get(userKey);
如果(用户!=null){
返回用户;
}
return recentlyAccessed.getUnchecked(userKey);//或.get()如果需要
}
}
你能展示一下你是如何使用Guava缓存用户的,这样我们就有了更多的上下文吗?在你的CacheLoader实现上写一个重载方法,返回给定的“旧”用户实例。isOnline()是真的。@Ray soo reload()因为javadocs中没有信息:计算或检索与已缓存的键对应的替换值。当CacheBuilder.refreshAfterWrite刷新现有缓存项时,或通过调用LoadingCache.refresh.No,没有一种方法可以像您尝试的那样执行此操作时,将调用此方法。不过,听起来你应该在用户离线时执行显式的invalidate
。