Heyho,
目前正在使用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));
修改
好吧,我可以用weighter来限制我的缓存大小。对于每个在线用户,我可以返回0和其他每个用户1.这将导致缓存保持在线用户。但是如果使用maximumSize和expireAfterAccess会很好。但CacheBuilder.weighter(...)不会阻止expireAfterAccess(...)设置以驱逐旧用户。修改
也许有可能以某种方式取消驱逐,但我不确定如何:/
与:Is it safe to reinsert the entry from Guava RemovalListener?
相关最高
答案 0 :(得分:0)
您链接的问题直接描述了如何处理此模式。
我使用一张地图和一个缓存。将地图用于仍在进行中的作业,并可能使用缓存的RemovealListener从地图中删除条目?
简单地说,如果有数据你不想被驱逐,它就不属于驱逐的数据结构。
对于您的用例,您需要维护已登录用户的地图和最近登录用户的缓存。当用户登录时,他们将存储在标准地图中。当他们注销时,他们的对象被移动到缓存中,这最终将逐出它们。
您可以(并且应该)在包含地图和缓存的对象中隐藏此行为。这可能类似于:
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
}
}