concurrentexception我不明白它在哪里是错误

时间:2012-01-26 09:17:32

标签: java concurrency

我收到此异常

Exception in thread "Thread-3" java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
at java.util.LinkedList$ListItr.next(LinkedList.java:696)
at ServerMultiThread.run(ServerMultiThread.java:89)
at java.lang.Thread.run(Thread.java:680)

来自此代码:

            synchronized(itemsList)
            {

                if(itemsList.isEmpty())
                {
                    item.initCounter();
                    itemsList.add(item);
                    pw.println("It's the first time you connect to server!");
                }
                else
                {

                    for(ItemClient itm : itemsList)
                    {

                    if(itm.equals(item))
                    {
                        int value = itm.getCounter();
                        value++;
                        itm.setCounter(value);
                        pw.println(itm.getCounter());

                    }
                    else
                    {
                        item.initCounter();
                        itemsList.add(item);
                        pw.println("It's the first time you connect to server!");   
                    }
                    }
                }
    }

第89行对应于此for(ItemClient itm : itemsList)。为什么我收到此错误?

3 个答案:

答案 0 :(得分:3)

您正在更改for-each循环中的LinkedList内容。 LinkedList迭代器的实现检查下一次调用next(),如果列表已更改并抛出异常(我知道......)。

答案 1 :(得分:2)

增强的for循环用于迭代给定的值集,但是在迭代期间,您正在修改相同的内容,这就是为什么会出现该错误,而是使用正常的for循环来执行这东西的东西。

此致

答案 2 :(得分:0)

可悲的是,没有简单的方法。正如其他人所说,你无法修改这种循环中的集合。您的另一个选择是使用正常的for循环。但是,通过索引访问LinkedList,如:

for(int i = 0; i < list.size(); i++) {
    list.get(i);
}

每个项目的 O(N)时间,因为每次都需要从头开始遍历链接列表。

如果链接列表对您的算法不重要,我建议您改为使用ArrayList并更改代码,如下所示:

for(int i = 0; i < itemsList.size(); i++) {

     itm = itemsList.get(i);
     if(itm.equals(item)) {
          int value = itm.getCounter();
          value++;
          itm.setCounter(value);
          pw.println(itm.getCounter());
     } else {
          item.initCounter();
          itemsList.add(item);
          pw.println("It's the first time you connect to server!");   
     }
}    

这不会抛出异常,但它仍然不是一段很好的代码,因为你在迭代时添加到列表中,而且永远不是一个好主意

我希望你有耐心阅读到目前为止!

我的最后建议是保存一个临时列表您需要添加的元素,并将它们附加到循环结束时的初始列表中。这样您就可以保留所有原始代码和LinkedList

LinkedList<ItemClient> tempList = new LinkedList<ItemClient>();
for(ItemClient itm: itemsList) {

     itm = itemsList.get(i);
     if(itm.equals(item)) {
          int value = itm.getCounter();
          value++;
          itm.setCounter(value);
          pw.println(itm.getCounter());
     } else {
          item.initCounter();
          tempList.add(item);
          pw.println("It's the first time you connect to server!");   
     }
} 

itemsList.addAll(tempList);