通过多个线程删除java.util.Collection元素

时间:2011-03-07 21:58:15

标签: java multithreading concurrency

在多线程模块中,我不关心它是否通过线程安全地写入java.util.Collection(例如java.util.Set)对象。它的作用是通过多个线程删除一些独立元素,这可能同时对同一元素执行删除。那么,会发生什么?该元素被删除,或者抛出任何异常?


克加

5 个答案:

答案 0 :(得分:5)

当您删除不同的对象时,甚至可能抛出ConcurrentModificationException。这取决于您正在使用的Set的实现:remove()方法可以迭代该集合。或者更糟糕的是:它可能会修改其他一些内部变量,并使该集合处于不一致状态而不会抛出任何异常。

有一个非常简单的解决方案:

Set safeSet = Collections.synchronizedSet(set);

如果你想迭代它,你仍然需要注意,如apidoc:http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedSet%28java.util.Set%29所述,但所有其他方法(包括删除)都没问题。

答案 1 :(得分:2)

结果无法预测。 Set的内部结构可能处于不一致且不可用的状态。

答案 2 :(得分:2)

'ConcurrentModificationException'如果你幸运的话。如果没有混乱。无论是使用Collections.synchronized *还是在其他对象上进行同步,都不要这样做。

答案 3 :(得分:2)

java.util.Set只是一个接口。行为取决于Set接口的实现。您不能使用多个线程访问HashSet,因为行为无法保证,但如果您这样做,可能会抛出ConcurrentModificationException。

答案 4 :(得分:1)

你可能不在乎,因为如果你这样做,你会认为Set会保持其完整性。但它不会。

您需要Collections.newSetFromMap(new ConcurrentHashMap<E, Boolean>());或使用某些同步。去除不是这里唯一的问题。如果您只使用HashSet,您也可以在Set中找到重复项,或者知道还有什么。

给定一个适当的Set实现来处理线程问题,然后一个线程将删除该项,另一个将找到不存在的项,这可以通过Set上的remove方法的返回值来确定。

请注意,如果要迭代集合,则在迭代期间删除元素时必须使用一些外部同步。