我使用以下番石榴缓存来存储特定时间的消息,等待可能的响应。所以我使用缓存更像是消息超时:
Cache cache = CacheBuilder.newBuilder().expireAfterWrite(7, TimeUnit.DAYS).build();
cache.put(id,message);
...
cache.getIfPresent(id);
最后,我需要在关闭时保留消息及其当前的“超时”信息 并在启动时恢复它,并使用每个条目的内部已过期时间。我找不到任何可以让我访问时间信息的方法,所以我可以自己处理。
gauva wiki 说:
您的应用程序不需要存储比 RAM 所能容纳的更多的数据。 (Guava 缓存是应用程序单次运行的本地缓存。它们不会将数据存储在文件中或外部服务器上。如果这不能满足您的需求,请考虑使用 Memcached 等工具。)
您认为这个限制地址也是一个在关闭时持续存在的“超时”映射吗?
我不相信有任何方法可以使用每个条目的过期值重新创建缓存——即使您确实使用了反射。您也许可以通过在单独的线程中使用
DelayedQueue
来模拟它,该线程显式地使应该过期的条目无效,但这是我认为您能做的最好的事情。
也就是说,如果您只是想查看过期信息,我建议您将缓存值包装在一个记住过期时间的类中,这样您就可以通过查找条目的值来查找条目的过期时间并调用
getExpirationTime()
方法或其他方法。
至少,新的 Guava 版本不应该打破这种方法。
不幸的是,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);
}