0

ConcurrentModificationException即使我使整个程序的所有方法同步(包括静态方法和方法),我也得到了一个main

我没有隐藏的迭代器。

  1. 这怎么可能呢?!
  2. 这是什么意思?
  3. 我该如何解决?
4

7 回答 7

6
  1. AConcurrentModificationException可能是由同一线程在迭代集合时操作集合引起的
  2. 这意味着在迭代集合时不要更改集合,除非通过Iterator.remove()orListIterator.add()方法
  3. 见 2。
于 2011-12-20T23:02:43.123 回答
3

当您遍历一个集合并在此期间从该集合中删除一个条目时,您会收到此异常。

例如

Collection<Object> objects = new ArrayList<Objects>(Arrays.asList("a","b"));
for (Object o : objects) {
    objects.remove(o); //throws exception
}

您必须将要删除的那些添加到另一个集合中,并在完成对列表的迭代后将其删除。否则,您通过它的 iterator() 迭代对象集合并在当前迭代器上调用 remove()。

于 2011-12-20T22:58:49.230 回答
3

ConcurrentModificationException 与同步无关。

它与在迭代时修改集合有关。正如 Lie Ryan 所指出的,完整的堆栈跟踪将帮助我们指出您是如何得到它的。

通常,要解决此问题,您不能在迭代集合时修改集合本身。

于 2011-12-20T23:00:44.710 回答
3

如果你运行这个

List<Object> list = new ArrayList<Object>();
for(Object obj : list)
    list.remove(obj);

你会得到一个商品化。如果不使用适当的函数,则无法在迭代集合时更改它。

这可以使用以下方法解决:

List<Object> list = new ArrayList<Object>();
for(Iterator<Object> itr = list.iterator(); itr.hasNext();)
    itr.remove();
于 2011-12-20T23:00:51.243 回答
3

好吧,首先,如果你看到它,这是可能的:如果鸟书和鸟不同意,相信鸟。

现在,这怎么可能发生?没有看到你的代码很难准确地说,但是异常堆栈跟踪将指向它发生的地方;你在这附近看到什么?

一般来说,很明显,当你有并发访问时,它就会发生。当你找到它发生的地方时,问问自己有什么线索可以到达那里。

于 2011-12-20T23:01:32.590 回答
1

同步方法在它运行的对象实例上放置一个锁。

如果对象 A 和 B 访问同一个集合,那么 A#doStuff 和 B#doStuff 是否同步并不重要——它们仍然可以同时执行。

要锁定集合,您可能需要锁定集合本身:方法主体中的 synchronized(collection) 或 Java 5 互斥锁(更好)。

(正如其他人所指出的那样,即使在单个线程中您也可以拥有 ConcurrentModificationException 的事实)。

于 2011-12-20T23:01:49.880 回答
1

ConcurrentModificationException的 javadoc包含答案:

请注意,此异常并不总是表示对象已被不同的线程同时修改。如果单个线程发出一系列违反对象约定的方法调用,则该对象可能会抛出此异常。例如,如果线程在使用快速失败迭代器迭代集合时直接修改了集合,则迭代器将抛出此异常。

解决它的方法是不要那样做。

即,(正如其他人所指出的)如果您需要同时迭代和修改,请使用迭代器提供的方法,而不是直接修改集合。

于 2011-12-20T23:07:08.810 回答