在JDK6.0或其他库中是否有任何Concurrent LinkedHashSet?

时间:2011-03-13 16:43:59

标签: java java.util.concurrent

我的代码抛出异常:

java.util.ConcurrentModificationException
        at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
        at java.util.LinkedList$ListItr.next(LinkedList.java:696)
        at java.util.AbstractCollection.addAll(AbstractCollection.java:305)
        at java.util.LinkedHashSet.<init>(LinkedHashSet.java:152)
        ...

我想要ConcurrentLinkedHashSet来修复它,

但我只在ConcurrentSkipListSet中找到了java.util.concurrent,这是TreeSet,而不是LinkedHashSet

在JDK6.0中获取ConcurrentLinkedHashSet的任何简便方法?

感谢您的帮助:)

4 个答案:

答案 0 :(得分:10)

ConcurrentModificationException与您正在考虑的表单中的并发性无关。这只意味着在迭代Collection时,有人(可能是你自己的代码 - 经常发生的事情;))正在改变它,即添加/删除一些值。

确保您使用Iterator从集合中删除值,而不是集合本身。

编辑:如果真的另一个线程同时访问Collection,那么从标准库获得的弱同步无论如何都是无用的,因为你必须在整个操作期间阻止Collection而不仅仅是一个添加/删除!即

之类的东西
synchronize(collection) {
   // do stuff here
}

答案 1 :(得分:4)

您始终可以使用Collections.synchronizedMap(myMap);创建同步集合。但是,尝试在迭代时更改地图(我假设是导致错误的原因)仍然是个问题。

来自synchronizedMap的文档:

返回由指定映射支持的同步(线程安全)映射。为了保证串行访问,必须通过返回的映射完成对支持映射的所有访问。

  

用户势在必行   手动同步返回   迭代任何一个时映射   集合视图......未能遵循   这个建议可能会导致   非确定性行为。

这是因为

  • 通常并发集合确实保证了原子获取/放置,但是在迭代期间没有锁定整个集合,这太慢了。迭代没有并发保证,实际上是针对地图的许多操作。

  • 如果你在迭代期间改变它并不是真正的并发,因为它不可能确定正确的行为 - 例如,如何协调你的迭代器返回hasNext == true并删除a(可能是下一个值)集合?

答案 2 :(得分:2)

有ConcurrentLinkedHashMap - https://code.google.com/p/concurrentlinkedhashmap/

您可以使用java.util.Collections.newSetFromMap(map)创建Set out of it

答案 3 :(得分:0)

不幸的是没有。您可以实现自己的,包装ConcurrentHashMap和ConcurrentLinkedQueue,但这不允许您轻松删除值(删除将是O(N),因为您必须遍历队列中的所有内容)... < / p>

你在使用LinkedHashSet的是什么?可能会建议替代品......