关闭时保留番石榴缓存

问题描述 投票:0回答:2

我使用以下番石榴缓存来存储特定时间的消息,等待可能的响应。所以我使用缓存更像是消息超时:

Cache cache = CacheBuilder.newBuilder().expireAfterWrite(7, TimeUnit.DAYS).build();
cache.put(id,message);
...
cache.getIfPresent(id);

最后,我需要在关闭时保留消息及其当前的“超时”信息 并在启动时恢复它,并使用每个条目的内部已过期时间。我找不到任何可以让我访问时间信息的方法,所以我可以自己处理。

gauva wiki 说:

您的应用程序不需要存储比 RAM 所能容纳的更多的数据。 (Guava 缓存是应用程序单次运行的本地缓存。它们不会将数据存储在文件中或外部服务器上。如果这不能满足您的需求,请考虑使用 Memcached 等工具。)

您认为这个限制地址也是一个在关闭时持续存在的“超时”映射吗?

java guava
2个回答
1
投票

我不相信有任何方法可以使用每个条目的过期值重新创建缓存——即使您确实使用了反射。您也许可以通过在单独的线程中使用

DelayedQueue
来模拟它,该线程显式地使应该过期的条目无效,但这是我认为您能做的最好的事情。

也就是说,如果您只是想查看过期信息,我建议您将缓存值包装在一个记住过期时间的类中,这样您就可以通过查找条目的值来查找条目的过期时间并调用

getExpirationTime()
方法或其他方法。

至少,新的 Guava 版本不应该打破这种方法。


1
投票

不幸的是,Guava 似乎没有公开这个功能,但如果你喜欢冒险并且绝对必须拥有这个功能,你可以随时使用反射。只需查看来源并看看您需要什么方法。一如既往地要小心,因为当 Guaval 内部实现发生变化时,您的代码可能会中断。下面的代码似乎适用于 Guava 10.0.1:

    Cache<Integer, String> cache = CacheBuilder.newBuilder().expireAfterWrite(7, TimeUnit.DAYS).build(new CacheLoader<Integer, String>() {
        @Override
        public String load(Integer key) throws Exception {
            return "The value is "+key.toString();
        }
    });
    Integer key_1 = Integer.valueOf(1);
    Integer key_2 = Integer.valueOf(2);
    
    System.out.println(cache.get(key_1));
    System.out.println(cache.get(key_2));
    
    ConcurrentMap<Integer, String> map = cache.asMap();
    
    Method m = map.getClass().getDeclaredMethod("getEntry", Object.class);
    m.setAccessible(true);

    for(Integer key: map.keySet()) {
        Object value = m.invoke(map, key);
        Method m2 = value.getClass().getDeclaredMethod("getExpirationTime", null);
        m2.setAccessible(true);
        Long expirationTime = (Long)m2.invoke(value, null);
        System.out.println(key+" expiration time is "+expirationTime);
    }
© www.soinside.com 2019 - 2024. All rights reserved.