关机时保持guava缓存

时间:2012-01-31 13:06:45

标签: java guava

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

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

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

gauva wiki说:

  

您的应用程序不需要存储比RAM中更多的数据。 (Guava缓存是一次运行应用程序的本地缓存。它们不会将数据存储在文件中或外部服务器上。如果这不符合您的需求,请考虑像Memcached这样的工具。)

您是否认为此限制还会在关机时持续存在“超时”映射?

2 个答案:

答案 0 :(得分: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);
    }

答案 1 :(得分:1)

我不相信有任何方法可以使用每个条目的到期值重新创建缓存 - 即使您使用反射也是如此。您可以通过在单独的线程中使用DelayedQueue来模拟它,该线程明确地使应该已过期的条目无效,但这是我认为您可以做的最好的。

也就是说,如果您只是对过期信息感兴趣,我建议将缓存值包装在一个记住过期时间的类中,这样您就可以查看条目的过期时间了。查找它的价值并调用getExpirationTime()方法或者你有什么。

至少,这种方法不应该破坏新的番石榴版本。