[concurrency-interest] Should CopyOnWriteArrayList implement RandomAccess?
concurrency at kuli.org
Thu Jun 27 11:14:55 EDT 2013
Am 27.06.2013 16:51, schrieb Yuval Shavit:
> This seems like over-sensitivity to backwards compatibility. There are
> no methods on RandomAccess, so I don't know why you would take a List of
> known type and cast it to RandomAccess (e.g. RandomAccess r = new
> COWAL()). In fact, I don't know why you would do *anything* with
> RandomAccess other than checking for it with instanceof; I suspect that
> if it had come into being in 1.5, it would have been an annotation
> instead of an interface.
First of all, an Annotation is - in this case - no way better than a
marker interface. Checking for RandomAccess is easy and simple by a
quick and fast instanceof. If it would be marked by an annotation,
checking for that would be much more complicated. (I personally don't
like the reflection-like usage of getClass() in user code.) And what
about subclasses or even anonymous classes? Aren't they random
accessible any more? And what if the interface is marked, but not the
implementation? Should you check every implemented interface for
Breaking user code is easy when a library only accepts RandomAccess
lists because it relies heavily on fast get() implementations.
Even ThreadDeath wasn't made package private for backwards compatibility.
The whole discussion seems to be rather academic to me. The volatile
read in COWAL.getArray() is so fast on most systems that you only have
to care in very specific situations, where you wouldn't rely on the
general implementation of RandomAccess anyway.
And, the Javadoc of RandomAccess claims that it's only a "rule of thumb"
that get() should be faster than iterator.next(). If you look into, for
example, java.util.Vector, you'll see that the difference is so marginal
that it would be hard to measure even in a loop of millions of iterations.
I'd rather see RandomAccess as just a hint that get() is "quite fast"
and independent of the list's size and the index parameter. So it's
perfectly clear that COWAL should implement this.
If you rely on get() not throwing IndexOutOfBoundsException after you
checked for size() before, then you'll have a problem in every
concurrent situation. This has nothing to do with COWAL, it's true for
Vector or even every other synchronized List.
More information about the Concurrency-interest