2012-12-04 84 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)你修改你的链表(你重新链接它),因此你得到那个错误;你的迭代器不再有效。