Re: Vector (was Re: Change character in string)
On 2009-03-14, Lew <noone@lewscanon.com> wrote:
Peter Duniho wrote:
The get() is synchronized.
But when I look at the source for 'Vector' I don't see 'get()' invoked in the
'equals()' implementation:
public synchronized boolean equals(Object o) {
return super.equals(o);
}
which calls:
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
ListIterator<E> e1 = listIterator();
ListIterator e2 = ((List) o).listIterator();
while(e1.hasNext() && e2.hasNext()) {
E o1 = e1.next();
Object o2 = e2.next();
The listIterator is AbstractList$Itr which has this next():
public E next() {
checkForComodification();
try {
E next = get(cursor); // HERE
lastRet = cursor++;
return next;
} catch(IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
The get() being called at HERE is that of Vector (it's abstract in
AbstracList), which is synchronized.
The same listIterator is used by SynchronizedArrayList but the get()
/it/ calls is that of the base unscynchronized ArrayList.
Either way of doing it is wrong: in one case you end up deadlocking
and in the other you're not synchronizing on all the data that you
need. And neither of these flaws is obvious to the user, or even
documented in any way that I know of.
I have always found this rather serious because, of all the methods
you can call on a List you'd expect equals() to be among the safer
ones. All sorts of algorithms rely on being able to use it all the
time - but perhaps that's my GUI bias shining through.
Cheers,
Bent D
--
Bent Dalager - bcd@pvv.org - http://www.pvv.org/~bcd
powered by emacs