为什么Java必须抛出并发修改异常?

为什么Java必须抛出并发修改异常?,java,c++,exception,iterator,Java,C++,Exception,Iterator,我想了解Java的迭代器。为什么它们被设计为抛出并发修改异常?在C++ STL中,可以在容器上迭代并修改内容,但为什么不能用java来完成呢?p> 编辑:更正问题。框架不正确。我不想解释为什么它们是这样设计的,我只想告诉你一个小秘密: 如果您在迭代期间从列表中删除,您将得到一个并发异常。 如果在迭代过程中使用迭代器删除,可能会由于其他原因导致并发异常 像这样的 for(Iterator<?> iter = list.getIterator(); iter.hasNext(); ) {

我想了解Java的迭代器。为什么它们被设计为抛出并发修改异常?在C++ STL中,可以在容器上迭代并修改内容,但为什么不能用java来完成呢?p>
编辑:更正问题。框架不正确。

我不想解释为什么它们是这样设计的,我只想告诉你一个小秘密:

如果您在迭代期间从列表中删除,您将得到一个并发异常。 如果在迭代过程中使用迭代器删除,可能会由于其他原因导致并发异常

像这样的

for(Iterator<?> iter = list.getIterator(); iter.hasNext(); )
{ 
   MyClass c = iter.getNext();
   if( //i need to remove this instance)
      iter.remove(iter);
}
将调用包装为synchronized或将变量标记为volatile可能有助于避免并发修改,因为这些修改将同步对对象的访问,从而防止您同时从多个源访问它

或者使用[奶牛名单]


我似乎无法掌握如何链接内容的窍门,因此今天……

您可以在迭代集合时修改它。你只需要用它

例如,如果另一个线程在迭代期间修改了集合,则可能会抛出。这比未定义的行为更可取

Java迭代器不是线程化的。可能存在多个线程,迭代器可能在这些线程中表现良好。

下面是一个例子,说明了当您在对列表进行迭代时,试图修改列表时迭代器会出现问题的原因

假设您的迭代器是使用索引实现的,如在ArrayList中:假设您的迭代器现在指向列表中的位置3。现在在位置1添加一个元素。迭代器不知道您做了什么更改,所以它仍然指向位置3,但位置3现在保留了以前位于位置2的元素,因为所有元素都向下移动。因此,您的迭代器现在将访问一个元素两次!那太糟糕了


因此,规则是,当您在对列表进行迭代时修改列表时,您必须从迭代器本身进行修改,以便迭代器知道如何使其位置与对列表的修改保持同步。如果您在不使用迭代器的情况下修改列表,迭代器将抛出ConcurrentModificationException,而不是自动损坏,例如多次访问元素。

这与多线程无关。修改基础集合会使迭代无效。仅当两个线程参与修改对象时,不一定会发生此异常。而且它们不做任何事情来防止并发修改不一定被抛出多线程代码中。当您在迭代集合时修改集合时会发生这种情况。即使在单线程应用程序中也会出现这种异常。迭代器是线程化的,这是从哪里来的?你的整个假设是一个大的非事实陈述…但是这是如何回答OP的问题,关于能够在C++中而不是在java中做这件事吗?我认为在答案中写一条关于它的注释是有意义的!