Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't my sample throw ConcurrentModificationException [duplicate]

I wrote this example following a test ConcurrentModificationException concept:

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

When I executed the above main method, ConcurrentModificationException doesn't get thrown and the output console prints the following result:

a
c

By with my knowledge of this issue, when in a loop for list, when modifying the list,a ConcurrentModificationException exception should be thrown. But why in my sample does this not occur?

like image 659
Sam Avatar asked Nov 10 '22 11:11

Sam


1 Answers

There is no guarantee that structural modifications to the list will throw a ConcurrentModificationException.

From the 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.

In this particular case, you're "lucky" (or "unlucky" depending on how you see it). The structural change goes unnoticed since the loop exists before another modification check is performed.

For a detailed explanation, refer to the answers in the dup:

  • Why isn't this code causing a ConcurrentModificationException?
like image 165
5 revs Avatar answered Nov 15 '22 13:11

5 revs