On Tue, May 15, 2018 at 5:34 PM, Stuart Marks <stuart.ma...@oracle.com> wrote:
> >> > Bringing replaceAll() to the public API exposes it as a single operation, > with its own semantics. > Note that Vector.replaceAll() holds the lock for the entire operation, not > merely around individual set() operations. It really is different from > performing individual set() operations. How many times the lock is acquired is an implementation detail, a non-obvious tradeoff even. vector.replaceAll holds the lock throughout, but vector.subList(0, size).replaceAll holds the lock for each element (sigh ... racily (really a bug!)). > Again, imagine this use case: there is a periodic background task that >> optimizes all the elements of a Vector >> vector.replaceAll(x -> optimized(x)) >> That should not break any iterations in progress. >> > > I don't think it's possible to do that correctly without holding a lock > around the entire iteration. I don't see why. > If the lock is held, CME can't occur, as a concurrent replaceAll() will > occur before or after the iteration, never in the middle. > > I don't see why - iteration is inherently non-atomic, so replaceAll could be called in the middle. > If an iteration over a Vector doesn't hold a lock, any read-modify-write > operations (consider a loop with a ListIterator on which set() is called) > can be interleaved with bulk operations (like replaceAll) which is clearly > incorrect. In such cases, CME should be thrown. > > Imagine your iterators are all read-only, and don't care whether they see an element or its replacement. > Also, this use case cannot be written today, because CME is thrown. ?? Imagine there's only one writer thread, with some Iterating reader threads. Every midnight, the writer thread optimizes all the elements for (int i = 0; i < size; i++) vector.set(i, optimized(vector.get(i)) This code has worked well since the '90s without CME. One day the maintainer notices shiny new Vector.replaceAll and "fixes" the code. """It's perfectly safe""". The CME is rare and so only caught when the maintainer has gone on to the next job. The CMEs only happen at midnight!