2

这篇文章的摘要:我有一组订购的物品,它们的顺序可能会随着时间而改变。我需要能够从多个线程迭代这个集合,每个线程可能还想更新项目的顺序。

例如,多个线程需要以String任意排序顺序访问键。它们的字符串不是根据它们的自然顺序排序的,而是根据一些可能改变的值(因此,一个 custom Comparator)。我最初的实现是使用 aTreeSet并在其上同步。如果任何键需要重新排序,线程将从映射中删除键,更新比较值,然后重新插入键。为了实现这一点,键是原生String的,但比较器可以访问值。这是一种奇怪的安排,其中键的顺序可能会随着时间而改变,但是由于更改的键总是在更改时被删除并重新插入,因此它似乎可以工作。String(我想如果s 被包裹在另一个对象中,它也可以工作。)

我最近意识到ConcurrentSkipListSet/ConcurrentSkipListMap实现基本上是线程安全的排序集(分别是映射)。现在看来我可以遍历键而不必锁定整个数据结构。但是,有没有一种方法可以使用它们原子地删除一个键并将其替换为另一个键,就像我在上面所做的操作一样,以便其他迭代线程不会错过该项目,而不必使用synchronize块?

如果有人可以为这种类型的操作提出更好的数据结构,我也全神贯注!

4

1 回答 1

3

有没有一种方法可以使用它们原子地删除一个键并将其替换为另一个键,就像我在上面所做的操作一样,以便其他迭代线程不会错过该项目,而不必使用同步块?

最简洁的答案是不。如果您需要删除并重新插入,我知道的任何集合都没有原子方法可以做到这一点。

也就是说,一种可能性是您在将其从跳过列表中删除之前重新插入该项目。这会导致重复,但可能比丢失条目更容易处理。您将在更改对象后重新插入它,以便它以不同的方式排序。这假设对象也将不相等。但是,如果正在处理列表的其他线程无法处理重复项,那么我认为您是 SOL。

于 2013-03-19T18:22:00.977 回答