2

本文内容摘要:我有一组订购商品,其订购可能随时间而改变。我需要能够从多个线程遍历这个集合,每个线程也可能需要更新这些项目的顺序。对ConcurrentSkipListMap/ConcurrentSkipListSet中的键重新排序的原子方法?

例如,多个线程需要以某种任意排序顺序访问String键。他们的字符串不是根据自然顺序排序,而是根据可能会改变的某些值进行排序(因此,自定义Comparator)。我最初的实现是使用TreeSet并对其进行同步。如果任何密钥需要重新排序,则线程将从地图中删除密钥,更新比较值并重新插入密钥。要实现这一点,密钥是本机String s,但比较器可以访问这些值。这是一种奇怪的安排,其中键的顺序可能会随着时间而改变,但是由于改变的键总是被移除并在改变时重新插入,所以它似乎起作用。 (我想这也可以工作,如果String小号包裹另一个对象中。)

我最近才知道原来ConcurrentSkipListSet/ConcurrentSkipListMap实现它们基本上是线程安全的有序集合的(相应的地图。)好像我现在可以循环访问密钥而不必锁定整个数据结构。但是,有没有一种方法可以使用它们以原子方式删除某个键并将其替换为另一个键,如上面所做的操作,以便其他迭代线程不会错过该项目,并且无需使用synchronize块?

如果任何人都可以为这种类型的操作建议更好的数据结构,我也是耳朵!

+1

这种设计会让我真的很紧张。比较器不应随时间而改变。 – 2013-03-19 18:22:59

+0

对于需要维护一组对象的订单可能会随时间而改变的内容,您会提出什么建议? – 2013-03-19 18:24:26

+0

每次都可以使用新的比较器进行排序的列表,或者,我会编辑我的StackOverflow问题,向我们提供有关使您需要这种数据结构的问题的更多详细信息。 ;) – 2013-03-19 18:29:12

回答

3

是有办法,我可以用它来去除原子键和另一个取代它,就像我上面所做的操作,让其他迭代线程不会错过的项目,而不必使用同步块?

简短的回答是否定的。如果您需要删除并重新插入,那么对于我所知的任何集合都没有原子方法。

也就是说,有一种可能性是您将之前的项目重新插入到之前,将其从跳过列表中删除。这会造成重复,但可能更容易处理,然后丢失一个条目。在更改对象之后,您将重新插入它,以便进行不同的排序。这假定该对象也是不平等的。但是,如果处理列表的其他线程无法处理重复项,那么我认为你是SOL。