我使用以下guava缓存来存储特定时间的消息,等待可能的响应。所以我使用缓存更像是消息超时:
Cache cache = CacheBuilder.newBuilder().expireAfterWrite(7, TimeUnit.DAYS).build();
cache.put(id,message);
...
cache.getIfPresent(id);
最后,我需要在关机时使用当前的“超时”信息来保留消息 并在启动时恢复它,每个条目的内部已过期时间。我找不到任何能让我访问时间信息的方法,所以我可以自己处理。
您的应用程序不需要存储比RAM中更多的数据。 (Guava缓存是一次运行应用程序的本地缓存。它们不会将数据存储在文件中或外部服务器上。如果这不符合您的需求,请考虑像Memcached这样的工具。)
您是否认为此限制还会在关机时持续存在“超时”映射?
答案 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()
方法或者你有什么。
至少,这种方法不应该破坏新的番石榴版本。