使用迭代器时出现 java.util.LinkedList$ListItr.checkForComodification 异常?

Getting java.util.LinkedList$ListItr.checkForComodification exception while using iterators?

我正在使用 listIterator() 访问和删除 class 中的 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");

        }
    }

你的 post 没有问题,只有陈述。但是,您描述的是预期的行为。来自 the docs

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the Iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. 

因此,为了防止这种情况发生,您需要防止作者在 reader 迭代的同时进行修改。使用 Collections.synchronizedList 方法。所有访问(readers 和作者)都应遵循此模式:

// store a single synchronized list reference for all access to use
nodeAttributes = Collections.synchronizedList(theLinkedList);

然后所有 reader 和作者都应该使用 synchronized (list) 块。

// Readers might do:
synchronized (list) {
  itr = nodeAttributes.listIterator();
  while (i.hasNext())
      ... do stuff ...
}

那些不进行迭代操作的线程可以只使用 Collections.synchronizedList 的 return 对象上的 "atomic" 方法,例如 add。这些方法在幕后使用同步块,因此它们只是一个 shorthand,当另一个在同步块中时它们仍会阻塞线程。

有很多方法可以处理并发 reader 和编写器。

  1. 一个是上面的,但它可能会在每个迭代器执行它的时候长时间锁定其他线程。
  2. 另一种是将列表复制到数组(在同步部分内),然后在锁外读取数组。
  3. 还有一个方法是使用 ReadWriteLock.

还有更多选项,具体取决于您的具体用例。