2012-12-04 116 views
1

我有一個試圖迭代(使用迭代器)的對象LinkedList,看看它們是否有任何衝突,如果是的話,從列表中刪除它。但是,我正在得到一個併發修改異常。我把它放在一個synchronized塊,我也想在一個try catch塊捕獲錯誤,既不似乎在所有幫助,代碼是在這裏:同步後Java併發修改異常

private void updateTP() { 
    synchronized (toiletpaper) { 
     Iterator<ToiletPaper> iter = toiletpaper.iterator(); 
     while (iter.hasNext()) { 
      ToiletPaper tp = iter.next(); 
      tp.update(1000, 700); 
      if (toilet.overlaps(tp)) { 
       System.out.println("tp splash!"); 
       toiletpaper.remove(tp); 
       menu.removeLife(); 
      } 
     } 
    } 
} 

對這個問題的任何想法,將不勝感激,我看過這裏和谷歌,他們都說要麼抓住例外或同步它,這似乎不工作,所以...請幫助。

回答

4

爲避免此例外情況,請改爲使用iter.remove()。這將通過迭代器實例刪除元素,而不是當前的調用,該調用將分別搜索並從列表中刪除 - 即併發修改。

+2

+1 - 和(至少在這種情況下)它與'synchronized'無關。這是一個不好的例外;它更像是一種「帶外修改」。 –

+0

這一切都很好,說這是命名不佳,但我還沒有看到一個替代名稱,我們毫不含糊地更好。 (而且讓人困惑的原因是「併發」有兩個不同的含義......「同時發生」和「涉及多重控制線程」。) –

2

由於您直接使用toiletpaper.remove(tp);修改集合,因此引發異常。您必須使用iter.remove()修改集合,同時迭代它。

2

當你做toiletpaper.remove(tp)你修改你的鏈表(你重新鏈接它),因此你得到那個錯誤;你的迭代器不再有效。