在HashSet中为ConcurrentModificationException提供的java是什么类?

时间:2015-09-04 09:48:56

标签: java multithreading collections synchronization

如果我们在HashSet的oracle文档中看到,它声明在迭代Set时,如果我们尝试操作它,它会抛出ConcurrentModificationException。这是理解的。

这类似于ArrayList或HashMap的情况。但是如果我们看到,Java提供了备用类,例如CopyOnWriteArrayList和ConcurrentHashMap。

为什么HashSet没有任何解决ConcurrentModificationException的类?或者即使它存在,请提请我注意。我不知道这样的课程

2 个答案:

答案 0 :(得分:1)

如果你想要" ConcurrentHashSet",其行为方式与ConcurrentHashMap相同,你可以使用Collections.newSetFromMap()并传递ConcurrentHashMap作为参数。

还有其他并发Set实施:例如ConcurrentSkipListSetCopyOnWriteArraySet

答案 1 :(得分:1)

TL; DR:A ConcurrentModificationException与线程无关!

您在java.util.concurrent中提到的“并发”收藏集旨在为Collections.synchronizedXXX提供快速而强大的替代方案。它们可以同时用于多个线程。

另一方面,当您在同一ConcurrentModificationException 中迭代时更改集合时,会发生Thread

final List<String> list = ...
for(final String s : list) {
    list.remove(s);
}

此代码每次都会在第二次迭代时抛出ConcurrentModificationException。同时从多个线程访问非线程安全Collection是未定义行为,可能永远不会产生ConcurrentModificationException。或者它可能会着火。

为了避免此类行为,请使用Iterator并要求其修改Collection

final List<String> list = ...
final Iterator<String> iter = list.iterator();
while(iter.hashNext()) {
    final String s = iter.next();
    iter.remove();
}

要回答您完全无关的问题,为了创建一个安全线程Set,只需使用以下内容:

final Set<String> threadSafe = Collections.newSetFromMap(new ConcurrentHashMap<>());

通过添加Collections.newSetFromMap,JDK设计人员没有看到创建ConcurrentHashSet类的重点。

总结

不要使用并发Collection来解决在单线程环境中不正确使用Collection的问题。它最多会变得更慢,最坏的情况会使你的代码以意想不到的方式运行,因为迭代器为并发集合提供的一致性保证更加轻松。