我正在使用listIterator()
来访问和删除实现LinkedList
的类中Runnable
的项目我同时也在程序的其他部分修改此列表的值
我在代码的这一部分使用listIterator()
的地方我从这个函数调用中获取ConcurrentModificationException
:
java.util.LinkedList中$ ListItr.checkForComodification
为什么我得到这个以及如何预防?
@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");
}
}
答案 0 :(得分:3)
你的帖子没有问题,只是一个声明。然而,您所描述的是预期的行为。来自the docs:
此类的iterator和listIterator方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时候对列表进行结构修改,除了通过Iterator自己的remove或add方法之外,迭代器将抛出一个ConcurrentModificationException的。
因此,为了防止这种情况,您需要在读者迭代的同时防止编写者进行修改。使用Collections.synchronizedList
方法。所有访问(读者和作者)都应遵循以下模式:
// 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 ...
}
那些在没有迭代的情况下运行的线程只能在Collections.synchronizedList
的返回对象上使用“原子”方法,例如add
。这些方法在封面下使用同步块,所以它们只是一个简写,它们仍然会阻塞线程而另一个在同步块中。
处理并发读者和作者的方法有很多种。
ReadWriteLock
。还有更多选项,全部取决于您的确切用例。