2012-04-13 55 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

相關問題