Я бы использовал ConcurrentSkipListMap
и периодически повторял бы карту, чтобы удалить устаревшие данные. Так как список пропусков неограничен, это открывает возможность утечки памяти, когда поток выселения не может наверстать упущенное, но на практике это кажется очень, очень маловероятным, если вы не сделаете что-то экстремальное. Я также сделал что-то подобное, когда я этого не делал хочу использовать фоновый поток:
static AtomicInteger cnt = new AtomicInteger();
Val put(K key, V val){
//Do the usual stuff
if(cnt.getAndIncrement() % 100 == 0){
//iterate map and evict stuff
}
}
if(cnt.getAndIncrement() % 100 == 0)
, возможно, был "умной оптимизацией", так что, возможно, вы могли бы просто повторять и выселять каждый раз, как предполагает Мэтт b.
О, только одна оговорка, когда вы делаете это ... Обязательно нарушайте равенство между различными объектами, когда отметки времени совпадают:
class Entity implaments Comparable<Entity>{
static AtomicInteger SEQ = new AtomicInteger();
int id = SEQ.getAndIncrement();
long timeStamp = System.currentTimeMillis();
int compareTo(Entity other){
// compare by timestamp
// If timestamps are equal, don't just return 0 yet!!
// Compare by id and return 0 ONLY IF the id equals.
// Otherwise entities disappear from your ordered map and
// it's really annoying to debug.
}