为什么我的示例不抛出 ConcurrentModificationException

Why doesn't my sample throw ConcurrentModificationException

我根据测试 ConcurrentModificationException 概念写了这个例子:

public class Person
{
    String name;
    public Person(String name)
    {
        this.name = name;
    }
}

public static void main(String[] args)
{
    List<Person> l = new ArrayList<Person>();
    l.add(new Person("a"));
    l.add(new Person("b"));
    l.add(new Person("c"));

    int i  = 0;
    for(Person s : l)
    {
        if(s.name.equals("b"))
            l.remove(i);
        i++;
    }

    for(Person s : l)
        System.out.println(s.name);
}

当我执行上面的 main 方法时,ConcurrentModificationException 没有被抛出并且输出控制台打印以下结果:

a
c

据我对这个问题的了解,在循环for list时,修改list时,应该会抛出ConcurrentModificationException异常。但为什么在我的样本中没有发生这种情况?

没有保证对列表的结构修改会引发ConcurrentModificationException

来自documentation

Note that fail-fast behavior cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast operations throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.

在这种特殊情况下,您是 "lucky"(或 "unlucky",具体取决于您的看法)。由于在执行另一次修改检查之前存在循环,因此结构更改未被注意到。

详细解释请参考dup中的答案:

  • Why isn't this code causing a ConcurrentModificationException?