RFR: 8001647: In-place methods on Collection/List

Paul Sandoz paul.sandoz at oracle.com
Fri Apr 19 05:54:46 PDT 2013


On Apr 19, 2013, at 2:29 PM, David Holmes <david.holmes at oracle.com> wrote:

> Hi Akhil,
> 
> This is only a partial review so far.
> 
> I have some issues with the ConcurrentModificationException strategy.
> 
> Taking ArrayList, the basic idea is that you want to detect 
> modifications that are concurrent with iteration - so the mutators up 
> the modCount and the iterator functions check to see if the modCount has 
> changed since the iterator was constructed. So you've then treated the 
> bulk operations as "iterations" and you check the modCount each time 
> through the loop. Problem is the modCount is not volatile so in all 
> likelihood the JIT is going to hoist the check of modCount out of the 
> loop and it will only be checked once. That's not incorrect as it is 
> "best effort" detection, but it might be surprising. (Note if existing 
> iterator methods get inlined the same problem can exist today.) Maybe it 
> is not worth trying to check this? The reality is that if the ArrayList 
> is really being modified concurrently - particularly if the size changes 
> - then you will just get exceptions (NPE, AIOOBE etc) not a nice neat CME.
> 
> It's late and I may have overlooked ssomething but in Vector all the 
> methods are synchronized yet you still check the modCount for changes ?? 
> But it is impossible for anyone to change modCount during a bullk 
> operation. It is only possible with iteration because a mutating method 
> in one thread can execute between the separate iterator hasNext()/next() 
> calls in another thread. So all the CME code can be dropped from the new 
> bulk methods.
> 

  Vector<Integer> v = new Vector<>(Arrays.asList(1, 2, 3));

  // Any of the following will throw a CME
  v.forEach(e -> v.add(e));
  v.iterator().forEachRemaining(e -> v.add(e));
  v.spliterator().forEachRemaining(e -> v.add(e));

Paul.


More information about the lambda-dev mailing list