On Jan 7, 2015, at 11:56 AM, Chris Hegarty <chris.hega...@oracle.com> wrote:

> On 07/01/15 10:47, Daniel Fuchs wrote:
>> On 07/01/15 11:31, Paul Sandoz wrote:
>>> 
>>> On Jan 7, 2015, at 10:45 AM, Remi Forax <fo...@univ-mlv.fr> wrote:
>>> 
>>>> A simple Java question, what this code does ?
>>>> 
>>>>  ArrayList<String> list = new ArrayList<>();
>>>>  list.add("foo");
>>>>  list.add("bar");
>>>>  for(String s: list) {
>>>>    list.remove(s);
>>>>  }
>>>> 
>>>> :(
>>>> 
>>> 
>>> We could improve the best-effort basis by which
>>> ConcurrentModificationException is thrown by snapshotting the
>>> collection size on construction of the iterator
> 
> This was my thought too.
> 
>  diff --git a/src/java.base/share/classes/java/util/ArrayList.java 
> b/src/java.base/share/classes/java/util/ArrayList.java
> --- a/src/java.base/share/classes/java/util/ArrayList.java
> +++ b/src/java.base/share/classes/java/util/ArrayList.java
> @@ -853,9 +853,10 @@
>         int cursor;       // index of next element to return
>         int lastRet = -1; // index of last element returned; -1 if no such
>         int expectedModCount = modCount;
> +        int itrSize = size;
> 
>         public boolean hasNext() {
> -            return cursor != size;
> +            return cursor != itrSize;
>         }
> 
>         @SuppressWarnings("unchecked")
> @@ -881,6 +882,7 @@
>                 cursor = lastRet;
>                 lastRet = -1;
>                 expectedModCount = modCount;
> +                itrSize--;
>             } catch (IndexOutOfBoundsException ex) {
>                 throw new ConcurrentModificationException();
>             }
> @@ -909,7 +911,7 @@
>         }
> 
>         final void checkForComodification() {
> -            if (modCount != expectedModCount)
> +            if (modCount != expectedModCount || size != itrSize)
>                 throw new ConcurrentModificationException();
>         }
>     }
> 

Under what conditions can the mod count be the same but the size is different? 
Would this not indicate there was a bug in some other method that made a 
structural change but did not update the mod count? Same apples to this:

  Object[] elementData = ArrayList.this.elementData;
  if (i >= elementData.length)
      throw new ConcurrentModificationException();

(Note as per usual in these discussions i am not referring to concurrent 
operation from multiple threads, under such conditions all bets are off.)

Unfortunately the change history in openjdk only goes back so far, and i agree 
with Doug that there might be some reason why this change was not made earlier 
on (it seems like an "obvious" thing to do).

Paul.


Reply via email to