标签: concurrentskiplistmap

我可以使用 identityHashCode 在尊重相同性的对象之间生成 compareTo 吗?

我想在两个对象之间实现一个简单的比较器,它的唯一要求是

  1. 它是一个有效的比较器(即定义所有对象的线性顺序)和
  2. .compare当且仅当对象相同时才返回 0 。

Comparator.comparing(System::identityHashCode)工作吗?还有其他方法吗?

动机: 我想构建一个集合,允许我将时间戳消息存储在线程安全集合中,该集合将支持诸如“获取时间戳位于 [a,b) 中的所有消息”之类的查询。

似乎番石榴TreeMultimap使用全局锁(编辑:如果用synchronizedSortedSetMultimap包装器包装),并且ConcurrentSkipListMap似乎每次只支持一个条目(它是一张地图,而不是多张地图)。所以我想只使用一组对:

ConcurrentSkipListSet<ImmutablePair<Float,Message>> db,

其中对按词法排序,首先按时间(使用Float.compareTo),然后按类似Comparator.nullsFirst(Comparator.comparing(System::identityHashCode)).

  • nullsFirst是有只是让db.subSet(ImmutablePair.of(a,null), ImmutablePair.of(b,null))查询半开时间区间[a,b)中。

  • 你明白为什么我关心比较器保持相同性:如果消息比较器对不相同的消息返回零,消息可能会被删除。

  • 你也明白了为什么我不需要比较器的其他东西:它就在那里,所以我可以使用ConcurrentSkipListSet. 我当然不想强加于用户(好吧,只是我 :-) 为Message.

  • 另一种可能的解决方案是使用 a ConcurrentSkipListMap<Float, Set<Message>>(带有线程安全的 Set<> 实例),但在内存方面似乎有点浪费,一旦消息被删除,我需要自己删除 emptySet 以节省内存。

编辑:正如一些人所指出的,identityHashCode 可能会产生冲突,实际上我现在已经确认在我的设置中存在这种冲突(大致相当于上面的 4K 集合,每个集合每个时间段填充 4K 消息)。这很可能是我看到一些消息丢失的原因。所以我现在比以往任何时候都更有兴趣找到某种方法来拥有一个真正尊重相同性的“不可知”比较运算符。实际上,64 位哈希值(而不是 identityHashCode 提供的 32 位值)可能就足够了。

java java.util.concurrent comparator skip-lists concurrentskiplistmap

12
推荐指数
1
解决办法
379
查看次数

如何删除要在ConcurrentSkipListMap中键入的元素?

我有一个ConcurrentSkipListMap。我需要删除低于的元素key

这是我可以执行的方法:

private ConcurrentNavigableMap<Double, MyObject> myObjectsMap = new ConcurrentSkipListMap<>();

//...

myObjectsMap = myObjectsMap.tailMap(10.25, false);
Run Code Online (Sandbox Code Playgroud)

看起来还不错,但是我对这些事实感到困惑:

1。

返回的地图受此地图支持,因此返回的地图中的更改会反映在此地图中,反之亦然。

这是否意味着垃圾回收器不会删除旧值?
即,我们删除了旧地图,现在有了新地图。但是此新地图得到了旧地图的支持。那么,旧地图会怎样?是将其删除还是将其永久保存在内存中?

2。

尝试插入超出其范围的键时,返回的映射将抛出IllegalArgumentException。

因此,现在我不能放置小于10.25且大于最后一个最大值的新键了吗?

我很困惑。然后如何正确地需要从ConcurrentSkipListMap中删除元素?

java concurrency java.util.concurrent sortedmap concurrentskiplistmap

3
推荐指数
1
解决办法
421
查看次数