Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用迭代器时获取java.util.LinkedList$ListItr.checkForComodification异常?_Java_Multithreading_Concurrency_Iterator - Fatal编程技术网

使用迭代器时获取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不好的事情可能会发生,而您只是隐藏了它们的后果:例如,您的读取迭代器不会完成对整个列表的迭代。只有一个有效的解决方案:同步所有线程的列表访问。我是否应该更改正在修改和读取列表的代码的其他部分(与此部分相同),因为我还是有例外。