Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8151423

No java.util.ConcurrentModificationException thrown when removing from a java.util.ArrayList in a for-each loop

    XMLWordPrintable

Details

    Description

      FULL PRODUCT VERSION :
      java version "1.8.0_74"
      Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
      Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux test-pc 3.19.0-51-generic #58~14.04.1-Ubuntu SMP Fri Feb 26 22:02:58 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      The following snippet of code doesn't throw a ConcurrentModificationException

      List<String> list = new ArrayList<>();
      list.add("0");
      list.add("1");
      list.add("2");
      list.add("3");

      for (String el : list) {
          if (el.equals("2")) {
              list.remove(el);
          }
          System.out.println(el);
      }

      Note that LinkedList exposes the same behavior (also for the last element) although it does a "less than" check in hasNext() instead of the not equals check in java.util.ArrayList:L846.

      Although it is stated in https://docs.oracle.com/javase/8/docs/api/java/util/ConcurrentModificationException.html that this exception thrown is not guaranteed, I believe that it has to be documented that the fail-fast behavior cannot be guaranteed even in cases where there are not multiple threads modifying the list (or change the behavior of the snippet above).

      The unexpected behavior in the above snippet is that the last element is never accessed but no exception is thrown

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      List<String> list = new ArrayList<>();
      list.add("0");
      list.add("1");
      list.add("2");
      list.add("3");

      for (String el : list) {
          if (el.equals("2")) {
              list.remove(el);
          }
          System.out.println(el);
      }

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      0
      1
      2
      Exception in thread "main" java.util.ConcurrentModificationException
      at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
      at java.util.ArrayList$Itr.next(ArrayList.java:851)
      ACTUAL -
      0
      1
      2

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.ArrayList;
      import java.util.List;

      public class ArrayListTest {

          public static void main(String[] args) {
              List<String> list = new ArrayList<>();
              list.add("0");
              list.add("1");
              list.add("2");
              list.add("3");

              for (String el : list) {
                  if (el.equals("2")) {
                      list.remove(el);
                  }
                  System.out.println(el);
              }
          }
      }
      ---------- END SOURCE ----------

      SUPPORT :
      YES

      Attachments

        Issue Links

          Activity

            People

              psonal Pallavi Sonal (Inactive)
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: