我的代码抛出异常:
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
的任何简便方法?
感谢您的帮助:)
答案 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的是什么?可能会建议替代品......