问题
I would like to have a HashMap<String, String>
, that every day at midnight, the cache will expire.
Please note that it's J2EE solution so multiple threads can access it.
What is the best way to implement it in Java?
回答1:
Although the other suggestions can work to time the expiration, it is important to note that :
Expiration of the hashmap can be done lazily
i.e. without any monitor threads !
The simplest way to implement expiration is thus as follows :
1) Extend hash map, and create a local nextMidtime (Long) variable, initialized to System.currentTime....in the constructor. This will be set equal to the Next midnight time, in milliseconds...
2) Add the following snippet to the first line of the the "containsKey" and "get" methods (or any other methods which are responsible for ensuring that data is not stale) as follows :
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);
回答2:
You want every single thing in the hashmap to be flushed at midnight?
If so I think I would create a new hashmap and substitute it for the original. Since the substitution is done in a single step and nothing else is trying to make the same change I believe it should be thread-safe.
Anything in mid-access will be allowed to finish it's access. This assumes that nothing else holds a reference to this hashmap.
If references to the hasmap are not consolidated to a single spot then I guess hashmap.clear()
is your best bet if the hashmap is synchronized.
If the hashmap is not synchronized then you are only able to modify it from a single thread, right? Have that thread call hashmap.clear()
.
I think that covers all the cases.
回答3:
You might also look into using Guava's CacheBuilder, which allows you to create a customized instance of their Cache interface. Among other useful features, CacheBuilder
allows you to set timed expiration, etc. to your own ends.
EDIT: I should note that you set expiration of entries based either on last access or last write, so this suggestion doesn't fit what you're asking for exactly, which is to flush everything once a night. You might still consider altering your design if using a third party API is an option. Guava is a very smart library IMHO, and not just for caching.
回答4:
java.util.Timer
and java.util.TimerTask
may prove to be useful.
Create a TimerTask
that can clear, or recreate, the HashMap
and via a Timer
instance arrange for it to be executed at midnight.
For example:
// 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);
The example just resets it every 100 milliseconds.
There is many Timer.schedule()
methods, some take a Date
and would allow you to specifiy midnight.
来源:https://stackoverflow.com/questions/8407969/java-cache-hashmap-expire-daily