使用迭代器时获取java.util.LinkedList$ListItr.checkForComodification异常?
我正在使用使用迭代器时获取java.util.LinkedList$ListItr.checkForComodification异常?,java,multithreading,concurrency,iterator,Java,Multithreading,Concurrency,Iterator,我正在使用listIterator()来访问和删除实现Runnable的类中的LinkedList中的项,我还同时修改程序其他部分中该列表的值 在这部分代码中,我使用了listIterator(),我从这个函数调用中得到了ConcurrentModificationException: java.util.LinkedList$ListItr.CheckForComodition 为什么会出现这种情况,如何预防 @Override public void run() {
listIterator()
来访问和删除实现Runnable
的类中的LinkedList
中的项,我还同时修改程序其他部分中该列表的值
在这部分代码中,我使用了listIterator()
,我从这个函数调用中得到了ConcurrentModificationException
:
java.util.LinkedList$ListItr.CheckForComodition
为什么会出现这种情况,如何预防
@Override
public void run()
{
while(true)
{
itr = nodeAttributes.listIterator();
while (itr.hasNext())
{
System.out.println("enterred");
nodeAttribute nA = (nodeAttribute) itr.next();
//System.out.println("for");
if(!nA.isMoving && !nA.moveQueue.isEmpty())
{
if(animator != null)
animator.stop();
animator = (Animator) nA.moveQueue.poll();
//itr.remove();
animator.start();
nA.isMoving = true;
System.out.print( "animator");
}
}
System.out.println( "looping");
}
}
你的帖子没有问题,只是一个声明。然而,您描述的是预期的行为。发件人: 这个类的迭代器和listIterator方法返回的迭代器是快速失效的:如果在迭代器创建后的任何时候,列表在结构上被修改,除了通过迭代器自己的remove或add方法,迭代器将抛出ConcurrentModificationException 因此,为了防止这种情况,您需要防止编写器在读卡器迭代的同时进行修改。使用该方法。所有访问(读卡器和写卡器)都应遵循以下模式:
// store a single synchronized list reference for all access to use
nodeAttributes = Collections.synchronizedList(theLinkedList);
然后,所有读卡器和写卡器都应该使用synchronized(list)
块
// Readers might do:
synchronized (list) {
itr = nodeAttributes.listIterator();
while (i.hasNext())
... do stuff ...
}
那些不进行迭代操作的线程可以在集合.synchronizedList
的返回对象上使用“原子”方法,例如添加
。这些方法在封面下使用同步块,因此它们只是一个简写,当另一个线程在同步块中时,它们仍然会阻止线程
有很多很多方法来处理并发的读者和作者
还有更多的选择,所有这些都取决于您的具体用例。您是否有类似堆栈跟踪的东西,以便知道它出现在哪一行?不,我不知道它发生在哪一行。您是否尝试过在内部for循环的内容周围使用try-catch?将内部循环放入
try-catch
语句后,不再发生异常。我不明白为什么代码会有奇怪的行为?或者说不再出现异常是偶然的吗?@AliNfr是的,这可能是偶然的。您正在违反黄金法则:不要同时在两个线程中读写未同步的列表。如果我只是通过捕获来忽略异常,会发生什么?似乎没有什么不好的事情发生。@AliNfr不好的事情可能会发生,而您只是隐藏了它们的后果:例如,您的读取迭代器不会完成对整个列表的迭代。只有一个有效的解决方案:同步所有线程的列表访问。我是否应该更改正在修改和读取列表的代码的其他部分(与此部分相同),因为我还是有例外。