2012-04-13 106 views
1

我有一个LinkedList对象列表。将元素添加到LinkedList时发生并发修改错误

List<LinkedList<File1>> backup = new ArrayList<LinkedList<File1>>(); 

的链表包含一些元素。我需要通过单击按钮动态添加其他元素。在执行此操作时,我收到了一个并发修改错误。我真的不明白为什么会出现这个错误。这里是代码:

private void jButton5ActionPerformed(java.awt.event.ActionEvent evt)  
{           
    // When JOIN button is clicked 
    int parent_node,dist_node; 
    // List<File1> temp_list = new ArrayList<File1>(); 
    File1 f_new = new File1(); 
    parent_node = Integer.parseInt(jTextField4.getText()); 
    dist_node = Integer.parseInt(jTextField5.getText()); 
    LinkedList<File1> tmp_bk = backup.get(parent_node); 
    System.out.println("parent node : " + parent_node); 
    System.out.println("dist node : " + dist_node); 
    System.out.println("no of lists : " + backup.size()); 
    f_new.nod = backup.size(); 
    f_new.dist = dist_node; 
    // temp_list.add(f_new); 
    tmp_bk.add(f_new); 

    ListIterator itr = it_bk.get(parent_node); 
    while(itr.hasNext()) 
    { 
     File1 f = (File1)itr.next(); 
     System.out.println("NODE : " + f.nod + "DIST : " + f.dist); 
    } 

}  
+0

我也有一个迭代器的数组列表,指向每个链表。 – Divyashree 2012-04-13 02:53:14

回答

6

这可能是因为你正在编辑列表,然后尝试使用原始迭代器。收集API doesn't allow that。您需要在编辑列表后创建新的迭代器。

例如,一个线程在另一个线程迭代它时通常不允许修改一个Collection。一般来说,在这些情况下迭代的结果是不确定的。某些迭代器实现(包括由JRE提供的所有通用集合实现的实现)可能会选择在检测到此行为时抛出此异常。这样做的迭代器被称为快速迭代器,因为它们快速且干净地失败,而在将来未定的时间冒着任意的,非确定性的行为冒险。

请注意,此异常并不总是表示某个对象已被另一个线程同时修改。如果单个线程发出违反对象合约的一系列方法调用,则该对象可能会抛出此异常。例如,如果一个线程在使用快速迭代器迭代集合的同时直接修改集合,迭代器将抛出此异常。

+0

嘿我明白了:) thnks很多,它的工作nw :) – Divyashree 2012-04-13 07:55:18

+1

@ Divyashree请接受答案..这可以帮助你获得更多的帮助 – Jayan 2012-04-13 08:39:22

1

首先,如果你真的希望人们把注意力放在你的问题上,那么你应该问问他们清楚和标准英语的问题。

其次,您应该提供一个指示,说明代码中的哪个位置会出现ConcurrentModificationError。

最后,什么是it_bk?它只是显示在你的代码中,没有任何解释。如果它是ListIterators的ArrayList,那么它的parent_node-th元素肯定有可能处于不确定hasNext()或next()是否安全的状态。我猜你用你的tmp_bk.add(f_new)修改了底层集合;所以一个预先存在的迭代器担心它的不变式可能会被违反。

一般建议:不要创建和保留迭代器(或它们的集合)。当你想要一个迭代器时,创建它,使用它并放弃它。

+0

雅对不起:) thnks的答复:) – Divyashree 2012-04-13 07:55:49

0

来自JDK 1.5的java.lang.Colletions不同步。在早期版本(jdk 1.4)中,你不会发现这个问题。

有多种解决方案可用于这些问题,您需要根据您的使用情况明智地选择其中之一。

  • 解决方案1:可以使用list.toArray()将列表转换为数组,并在数组上进行迭代。如果列表很大,则不建议使用此方法。

  • 回答2:整个列表可以通过将代码包装在同步块中进行迭代来锁定。如果高度并发,这种方法会对应用程序的可伸缩性产生不利影响。

  • 回答3:JDK 1.5为您提供了ConcurrentHashMap和CopyOnWriteArrayList类,它们提供了更好的可伸缩性,ConcurrentHashMap.iterator()返回的迭代器在保留线程安全性时不会抛出ConcurrentModificationException。

  • 回答4:通过Iterator“it”删除当前对象,该对象具有对下层集合“myStr”的引用。 Iterator对象为此提供了it.remove()方法。

+0

thnks很多:)你的职位是vry帮助:) – Divyashree 2012-04-13 07:56:09

相关问题