我有这样的事情:
private final Cache<Long, BlockingDeque<Peer>> peers = CacheBuilder.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES)
.build();
public class Peer {
public void hanleRequest(String request) { ... }
//....
}
Cache
仅提供两项政策:expiredAfterWrite
和expireAfterAccess
。第一个和第二个都适合我。
我希望 BlockingDeque<Peer>
实体在最后一次调用属于该Peer#handleRequest()
的{{1}}对象之一的Peer
方法后的10分钟内到期。方法BlockingDeque
重置到期计数器。
我想要 Peer#handleRequest()
对象的任何其他方法都不会重置计数器。
我想要 peers.get(key)也不会重置计数器。
示例
Peer
问题
peers.getIfPresent(key); // doesn't reset counter
peers.getIfPresent(key).add(new Peer()); // doesn't reset counter
peers.getIfPresent(key).remove(peer); //doesn't reset counter
peers.getIfPresent(key).handleRequest(request); // RESET counter!
,Cache
,ExpiringMap
或任何其他番石榴地图的帮助下,这可能吗? MapMaker
。该线程将每5-15秒遍历整个映射并检查是否有任何实体过期 更新: 这是一个很好的解决方案吗?我认为,ConcurrentHashMap
是一个将对每个用户请求执行的操作,因此它的性能保持在第一位。 handleRequest
缓存中的近似BlockingDeque
个对象接近10,一个双端队列中的peers
对象的近似数量为2。
Peer
答案 0 :(得分:3)
首先说一句:你问的问题有点像XY问题,请参阅: https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem 所以也许一些你真正想要实现的背景会很好。
从字面上理解问题,我会做以下事情:
对“不重置计数器”访问使用第二个缓存而不过期。将删除侦听器添加到对等缓存,以从第二个缓存中删除该值。也许只是一个HashMap也没关系。资源使用情况实际上由对等缓存控制。
答案 1 :(得分:1)
@ cruftex建议使用第二个缓存很好。
关于您更新的问题,您无需在“更新”值之前使其无效,只需更新它:
public class Peer {
public void handleRequest(String request) {
BlockingDeque<Peer> deque = peers.getIfPresent(key);
if (deque != null) {
peers.put(key, deque);
}
//...
}
//....
}