我希望有一个HashMap<String, String>
,每天午夜,缓存都会过期。
请注意,它是J2EE解决方案,因此多个线程可以访问它。
在Java中实现它的最佳方法是什么?
答案 0 :(得分:6)
虽然其他建议可以用于计算到期时间,但重要的是要注意:
可以懒惰地完成hashmap的到期
即。没有任何监控线程!
实施过期的最简单方法如下:
1)扩展哈希映射,并创建一个本地的nextMidtime(Long)变量,在构造函数中初始化为System.currentTime ....这将被设置为等于下一个午夜时间,以毫秒为单位......
2)将以下代码段添加到“containsKey”和“get”方法的第一行(或任何其他负责确保数据不陈旧的方法),如下所示:
if (currentTime> nextMidTime)
this.clear();
//Lets assume there is a getNextMidnight method which tells us the nearest midnight time after a given time stamp.
nextMidTime=getNextMidnight(System.currentTimeInMilliseconds);
答案 1 :(得分:4)
您希望在午夜时间刷新hashmap中的每一件事吗?
如果是这样,我想我会创建一个新的hashmap并将其替换为原始的。由于替换是在一个步骤中完成的,并且没有其他任何东西试图进行相同的更改,我认为它应该是线程安全的。
任何处于访问中途的内容都将被允许完成访问。这假定没有其他内容可以保存对此hashmap的引用。
如果对hasmap的引用没有合并到一个地点,那么如果哈希图是同步的,我猜hashmap.clear()
是你最好的选择。
如果hashmap没有同步,那么你只能从一个线程修改它,对吧?让该线程调用hashmap.clear()
。
我认为这涵盖了所有案例。
答案 2 :(得分:3)
您可能还会考虑使用Guava的CacheBuilder
,它允许您创建其Cache
界面的自定义实例。在其他有用的功能中,CacheBuilder
允许您为自己的目的设置定时到期等。
编辑:我应该注意您根据last access或last write设置了条目的到期时间,因此这个建议不符合您的要求,这是每晚冲洗一次。如果使用第三方API,您可能仍会考虑更改您的设计。 Guava是一个非常聪明的图书馆恕我直言,而不仅仅是缓存。
答案 3 :(得分:2)
java.util.Timer
和java.util.TimerTask
可能会证明有用。
创建一个TimerTask
,可以清除或重新创建HashMap
,并通过Timer
实例安排在午夜执行。
例如:
// Public single shared hash map.
static Map<String, String> cached_map_ = new HashMap<String, String>();
public class Hash_map_resetter
extends TimerTask
{
// Constructor takes reference to containing
// Timer so it can reset itself after execution.
Hash_map_resetter(Timer a_timer) { timer_ = a_timer; }
// Clear cache.
public void run()
{
cached_map_ = new HashMap<String, String>();
System.out.println("Cached cleared");
timer_.schedule(new Hash_map_resetter(timer_), 100);
}
// Reference to containing Timer.
private final Timer timer_;
}
// Example initiation.
Timer t = new Timer();
t.schedule(new Hash_map_resetter(t), 100);
该示例每100毫秒重置一次。
有许多Timer.schedule()
方法,有些方法需要Date
,并允许您指定午夜。