是否有并发和自我到期& java中的有序哈希映射

时间:2011-05-26 23:54:51

标签: java map guava

我正在使用google guava中的ConcurrentHashMap(通过MapMaker),但该实现并未订购。 google guava中有ConcurrentSkipListMap,但该结构无法过期。

是否有任何结构可以兼顾两者?

7 个答案:

答案 0 :(得分:2)

我会使用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)可能是一个“聪明的优化”,所以也许你可以像matt 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.
}

答案 1 :(得分:1)

扩展java.util.LinkedHashMap并覆盖removeEldestEntry()以执行您想要的任何操作。

答案 2 :(得分:0)

听起来你有非常具体和不寻常的要求。你可能不得不自己写。

答案 3 :(得分:0)

如果您有一个有序的地图(我假设订购时间基于时间戳),那么每当您从地图添加或获取项目时,您只需从地图中的最小有序值扫描到当前时间戳 - 60秒并删除任何不足之处。 Map的ordered属性意味着您无需在每次操作时扫描完整列表。

答案 4 :(得分:0)

为什么不使用两张有序地图?一个由时间戳键入,用于查找过期事件。另一个由UUID键入,用于查找事件。删除过期事件时,请使用事件的UUID从第二个地图中删除。

答案 5 :(得分:0)

听起来您想要并发到期地图的有序视图。您可以从ForwardingMap

构建一个

答案 6 :(得分:0)

良好的到期地图实施很难得到。除了番石榴,您可以查看ExpiringMap。交换已排序的地图实现以满足您的需求应该相当简单。