【发布时间】:2023-03-21 03:41:01
【问题描述】:
我正在使用来自 google guava 的 ConcurrentHashMap(通过 MapMaker),但没有订购该实现。
google guava 中有ConcurrentSkipListMap,但该结构不会过期。
有什么结构可以两者兼得吗?
【问题讨论】:
我正在使用来自 google guava 的 ConcurrentHashMap(通过 MapMaker),但没有订购该实现。
google guava 中有ConcurrentSkipListMap,但该结构不会过期。
有什么结构可以两者兼得吗?
【问题讨论】:
我会使用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.
}
【讨论】:
扩展 java.util.LinkedHashMap 并覆盖 removeEldestEntry() 以执行您希望它执行的任何操作。
【讨论】:
听起来您有非常具体和不寻常的要求。您可能必须自己编写。
【讨论】:
如果你有一个有序的地图(我假设排序是基于时间戳的),那么无论何时你从地图中添加或获取项目,你都可以简单地从地图中排序最小的值扫描到当前时间戳 - 60 秒,并删除任何不足之处。 Map 的有序属性意味着您无需在每次操作时扫描完整列表。
【讨论】:
为什么不只使用两个有序映射?一个以时间戳为键,用于查找过期事件。另一个由 UUID 键入,用于查找事件。移除过期事件时,使用事件的 UUID 从第二个地图中移除。
【讨论】:
听起来你想要一个并发过期地图的有序视图。您可以从ForwardingMap 构建一个
【讨论】:
很难找到好的过期地图实现。除了番石榴,你可以看看ExpiringMap。换入排序的地图实现以满足您的需求应该相当简单。
【讨论】: