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);
            }
            //...
        }
        //....
    }