RFR: 8001647: In-place methods on Collection/List
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));
More information about the lambda-dev