• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Multiple thread accessing List (ArrayList, Vector)

 
Praveen Sharma
Ranch Hand
Posts: 129
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I am trying to understand the difference between an ArrayList and a Vector. I wrote a sample program where :
- Thread 1 just iterates through the List
- Thread 2 modifies the list



As expected I run into a IllegalStateException where two threads access the same list.
[Exception is thrown at Thread-2]

Now, to make the program work I replace the ArrayList with Vector. And going by the definition of Vector my logic should work.

But still it does not.
Can some one explain why Vector does not work.
Thanks.

[Note: Making the progam work is not my intention here, I can add some syncronized blocks to make it work]
 
Steve Luke
Bartender
Posts: 4181
21
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Under what conditions does the ListIterator#remove() method throw an IllegalStateException? You should read the method's JavaDoc for help. As a hint, it has nothing to do with threading.

What are you trying to test?
Why do you think using synchronized blocks would prevent the IllegalStateException?
 
Ireneusz Kordal
Ranch Hand
Posts: 423
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
look here:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html

The Iterators returned by Vector's iterator and listIterator methods are fail-fast: if the Vector is structurally modified at any time after the Iterator is created, in any way except through the Iterator's own remove or add methods, the Iterator will throw a ConcurrentModificationException.


Iterator from MyThread1 throws exception, because Vector is modified in MyThread2 (in other way than throug this iterator's own remove method).
 
Steve Luke
Bartender
Posts: 4181
21
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ireneusz Kordal wrote:look here:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html

The Iterators returned by Vector's iterator and listIterator methods are fail-fast: if the Vector is structurally modified at any time after the Iterator is created, in any way except through the Iterator's own remove or add methods, the Iterator will throw a ConcurrentModificationException.


Iterator from MyThread1 throws exception, because Vector is modified in MyThread2 (in other way than throug this iterator's own remove method).


That would be the problem if the exception thrown was a ConcurrentModificationException in Thread1 but it never gets to that point. The program throws an IllegalStateException in Thread2 when it calls the iter.remove() method. This is because he is calling the iter.remove() without incrementing the iterator to a point where it can remove something. He must call iter.next() before calling iter.remove() to fix the IllegalStateException.

After that he would get the ConcurrentModificationException. Vector synchronizes individual accesses to the collection by synchronizing its methods but does not synchronize multiple dependent accesses to the collection, such as iterating over it. Since the iterator is a view which expects a consistent order in which to find the next value to get it can not be done when its get calls are interrupted by modification of the underlying collection. There are two ways to fix it - one is to put a synchronized(l) {} block around all iterating code, and another would be to use a collection which allows concurrent modification, like the CopyOnWriteArrayList or if you can use a Queue instead of a List, the ConcurrentLinkedQueue. Both of these are in Java 1.5+.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic