Re: Vector (was Re: Change character in string)
On 2009-03-14, Lew <noone@lewscanon.com> wrote:
Now I have quite the mental exercise ahead of me to figure out why
'Vector#equals()' deadlocks and 'SynchronizedList#equals()' doesn't.
The listIterator that ArrayList uses to access the other lists's
objects isn't synchronized. It is provided by the backing list and
doesn't get wrapped by SynchronizedList.
Vector's calls to retrieve the elements from the other Vector are
synchronized since it calls Vector.get() to do so, via a ListIterator.
Therefore, when a has been locked by one thread and it is trying to
access b's elements but b has been locked by the other thread, there
is a deadlock for Vector but not for a SynchronizedList.
Incidentally, the following code shows that you can't really rely upon
synchronizing the data structures. The code will cause concurrent
modification exceptions for Vector and SynchronizedList. Well, and
plain ArrayList.
What we need is strict two-phase locking. Or something else that
actually works.
Cheers,
Bent D
import java.util.*;
public class Test
{
public static void main(String args[])
{
List<Integer> a = createList();
List<Integer> b = createList();
populate(a);
populate(b);
Thread t1 = new Thread(new Equalizer(a, b));
// call new Mutator(a) instead and it should work
Thread t2 = new Thread(new Mutater(b));
t1.start();
t2.start();
}
private static List<Integer> createList()
{
//
//return Collections.synchronizedList(new ArrayList<Integer>());
//return new ArrayList<Integer>();
return new Vector<Integer>();
}
private static void populate(List<Integer> l)
{
for (int ii = 0; ii < 1000; ++ii) l.add(ii);
}
static class Equalizer implements Runnable
{
List<Integer> list1, list2;
public Equalizer(List<Integer> l1, List<Integer> l2)
{
list1 = l1;
list2 = l2;
}
public void run()
{
for (int ii = 0; ii < 1000; ++ii) list1.equals(list2);
}
}
static class Mutater implements Runnable
{
List<Integer> list;
public Mutater(List<Integer> l)
{
list = l;
}
public void run()
{
for (int ii = 0; ii < 1000; ++ii)
{
list.clear();
populate(list);
}
}
}
}
--
Bent Dalager - bcd@pvv.org - http://www.pvv.org/~bcd
powered by emacs