0

当我们运行上面的程序时,我们会java.util.ConcurrentModificationException立即得到ArrayList修改。发生这种情况是因为ArrayList迭代器在设计上是快速失败的。这意味着一旦迭代器被创建,如果ArrayList被修改,它会抛出一个ConcurrentModificationException.

public class ConcurrentListExample {

    public void someMethod() {
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");

        // get the iterator
        Iterator<String> it = list.iterator();

        //manipulate list while iterating
        while (it.hasNext()) {
            String str = it.next();
            System.out.println(str);
            if (str.equals("2")) {
                list.remove("5");
            }
            if (str.equals("3")) {
                list.add("3 found");
            }
            if(str.equals("4")) {
                list.set(1, "4");
            }
        }
    }
}

但如果我们Employee上课:

public class Test {
    public static void main(String[] args) {
        List al = new ArrayList();
        Employee ee = new Employee(1, "anoj");
        Employee ee1 = new Employee(2, "hai");
        al.add(ee);
        al.add(ee1);
        Iterator it = al.iterator();
        while (it.hasNext()) {
            Employee hh = (Employee)it.next();
            if (hh.getName().equals("anoj")) {
                al.remove(0);
                System.out.println(al);
            }
        }
    }
}

我没有得到一个ConcurrentModificationException.

4

4 回答 4

2

您不能使用迭代器同时修改和打印操作。它支持add()remove()

于 2013-09-30T20:23:07.887 回答
1

它不会第二次失败,因为iterator返回anoj最后。所以hasNext返回 false 并且next永远不会被调用,因此 no ConcurrentModificationException

只需移动ee1上面的加法,ee它就会失败

注意ArrayList这是关于 1. 为什么最后返回 anoj 和 2.为什么hasNext不抛出 CME 的内部实现。

于 2013-09-30T20:38:20.167 回答
1

检查并发修改异常气体是一个缺陷,如果您删除 ArrayList 的倒数第二个元素,它不会抱怨但会跳过最后一个条目。

发生这种情况是因为它在检查并发修改之前检查它是否已迭代 size() 次。

于 2013-09-30T20:38:25.943 回答
0

我认为正确的解释是来自ConcurrentModificationExcetion 的 javadocs 的摘录:

请注意,不能保证快速失败的行为,因为一般来说,在存在不同步的并发修改的情况下,不可能做出任何硬保证。快速失败操作会尽最大努力抛出 ConcurrentModificationException。因此,编写一个依赖此异常来确保其正确性的程序是错误的:ConcurrentModificationException 应该仅用于检测错误。

于 2013-09-30T20:40:59.623 回答