Java Guava缓存:通过删除策略手动管理
我有类似这样的东西:Java Guava缓存:通过删除策略手动管理,java,garbage-collection,guava,Java,Garbage Collection,Guava,我有类似这样的东西: private final Cache<Long, BlockingDeque<Peer>> peers = CacheBuilder.newBuilder() .expireAfterAccess(10, TimeUnit.MINUTES) .build(); public class Peer { public void hanleRequest(String request) { ... } //
private final Cache<Long, BlockingDeque<Peer>> peers = CacheBuilder.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES)
.build();
public class Peer {
public void hanleRequest(String request) { ... }
//....
}
问题
Cache
、ExpiringMap
、MapMaker
或任何其他番石榴地图的帮助下,这可能吗ConcurrentHashMap
,另外还有守护进程线程。该线程将每隔5-15秒遍历整个映射,并检查是否有任何实体过期handleRequest
是一个将在每个用户请求上执行的操作,因此它的性能保持在第一位。Peer
缓存中的近似BlockingDeque
对象接近10个,一个deque中的Peer
对象的近似数量为2个
private final Cache<Long, BlockingDeque<Peer>> peers = CacheBuilder.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES) //CHANGE TO WRITE POLICY
.build();
public class Peer {
public void hanleRequest(String request) {
BlockingDeque<Peer> deque = peers.getIfPresent(key);
peers.invalidate(key);
peers.put(key, deque);
//...
}
//....
}
private final Cache peers=CacheBuilder.newBuilder()
.expireAfterWrite(10,TimeUnit.MINUTES)//更改为写入策略
.build();
公共类对等{
public void hanleRequest(字符串请求){
BlockingDeque-deque=peers.getIfPresent(键);
失效(密钥);
同级。put(键,德克);
//...
}
//....
}
首先,请注意:您提出的问题闻起来像XY问题,请参见:
所以,也许你真正想要达到的背景是好的
从字面上理解这个问题,我会做以下几点:
对“不重置计数器”访问使用第二个未过期的缓存。将删除侦听器添加到对等缓存,以从第二个缓存中删除该值。也许只是一个HashMap也可以。资源使用实际上由对等缓存控制。@cruftex建议使用第二个缓存是可以的 关于更新的问题,您不需要在“更新”值之前使其无效,只需更新它:
public class Peer {
public void handleRequest(String request) {
BlockingDeque<Peer> deque = peers.getIfPresent(key);
if (deque != null) {
peers.put(key, deque);
}
//...
}
//....
}
公共类对等{
公共无效HandlerRequest(字符串请求){
BlockingDeque-deque=peers.getIfPresent(键);
如果(deque!=null){
同级。put(键,德克);
}
//...
}
//....
}
可以将缓存
和长
作为参数传递给对等
构造函数,并在handleRequest()中调用Cache.get(key)
?这将重置到期计数器。@fge是的,但问题是如何在缓存上不重置到期计数器。get
Operation此方法将重置计数器。请注意,我从来没有告诉过将值分配给任何变量。关于Guava缓存清理行为,请记住,从文档:使用CacheBuilder构建的缓存不会“自动”执行清理和逐出值,或者在值过期后立即执行清理和逐出值,或者诸如此类。相反,它在写操作期间或偶尔读操作期间(如果写操作很少)执行少量维护。
更不用说它在设计上不是超细粒度的。@fge查看我问题的更新部分,请查看。在那里我发布了整个上下文。问题很不一样,但代码是一样的。似乎我不明白。你能举个例子吗?
public class Peer {
public void handleRequest(String request) {
BlockingDeque<Peer> deque = peers.getIfPresent(key);
if (deque != null) {
peers.put(key, deque);
}
//...
}
//....
}