【问题标题】:Java Concurrent Modification Exception after synchronizing同步后Java并发修改异常
【发布时间】:2012-11-21 15:09:56
【问题描述】:

我有一个我试图迭代的对象的 LinkedList(使用迭代器),看看它们是否有任何冲突,如果有,请将其从列表中删除。但是,我收到了一个并发修改异常。我把它放在一个同步块中,我也尝试在一个 try catch 块中捕获错误,似乎都没有帮助,代码在这里:

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();
            }
        }
    }
}

对此问题的任何想法将不胜感激,我查看了here和google,他们都说要么捕获异常要么同步它,这似乎都不起作用所以......请帮忙。

【问题讨论】:

    标签: java iterator linked-list synchronized


    【解决方案1】:

    为避免该异常,请改用iter.remove()。这将通过迭代器实例删除元素,而不是当前调用,后者分别从列表中搜索和删除 - 即并发修改。

    【讨论】:

    • +1 -- 并且(至少在这种情况下)它与synchronized 无关。这是一个名字不好的异常;它更像是“带外修改”。
    • 可以说它的名字很糟糕,但我还没有看到我们明确更好的替代名称。 (它让人困惑的原因是“并发”有两个不同的含义......“同时发生”和“涉及多个控制线程”。)
    【解决方案2】:

    它会引发异常,因为您正在使用toiletpaper.remove(tp); 直接修改集合。您必须使用iter.remove() 来修改集合,同时对其进行迭代。

    【讨论】:

      【解决方案3】:

      当您执行toiletpaper.remove(tp) 时,您会修改您的链接列表(重新链接它),因此您会收到该错误;您的迭代器不再有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-01
        • 1970-01-01
        • 2016-11-19
        相关资源
        最近更新 更多