• Post Reply Bookmark Topic Watch Topic
  • New Topic

About Iterator

 
Ricky Wang
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I know that the iterators returned by the java.util.List's iteraotr() are fail-fast. But I do not understand the reason of this constrain.
Could anybody give me some examples to explain that if I violate this rule and it assumes that the Iterator would not throws ConcurrentModificationException, what would the inconsistent situation happen?
Thanks for any reply.
 
Joe Ess
Bartender
Posts: 9361
11
Linux Mac OS X Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I believe you are asking what harm can come to a collection if we are iterating over it and manipulate it without the safeguards on Iterator.
Let's say we are iterating through an ArrayList containing the following items:
ArrayList al contains {1,2,3,4,5,6,7,8,9,10}
Our Iterator is pointing at item 5. Let's say our logic has determined that 5 is to be processed and deleted. We process and delete, using al.remove(Object). Our list not contains:
{1,2,3,4,6,7,8,9,10}
What should iterator.next return next? Item 6 would be next according to the original list, but it occupies the place in the list that used to be occupied by 5. Item 7 should be next if we were just iterating by index, but that would leave 6 unexamined.
I saw some code like this before the Collections framework was released. It made for some interesting debug sessions when, for the reason above, an event queue was returning the odd-numbered event first, then half the even, then half of the remainder. . .
 
Ricky Wang
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Joe Ess:
I believe you are asking what harm can come to a collection if we are iterating over it and manipulate it without the safeguards on Iterator.
Let's say we are iterating through an ArrayList containing the following items:
ArrayList al contains {1,2,3,4,5,6,7,8,9,10}
Our Iterator is pointing at item 5. Let's say our logic has determined that 5 is to be processed and deleted. We process and delete, using al.remove(Object). Our list not contains:
{1,2,3,4,6,7,8,9,10}
What should iterator.next return next? Item 6 would be next according to the original list, but it occupies the place in the list that used to be occupied by 5. Item 7 should be next if we were just iterating by index, but that would leave 6 unexamined.
I saw some code like this before the Collections framework was released. It made for some interesting debug sessions when, for the reason above, an event queue was returning the odd-numbered event first, then half the even, then half of the remainder. . .


Thanks for your reply
If we assume that a custom LinkedList dose not have a index to get(like get(int)) it's element within it(LinkedList)and could only iterate through a Iteraot.next() or a Enumerator.next().
If some threads are iterating the LinkedList and some other threads are modifying it(add or delete elements), what harm can come to such a LinkedList .
[ November 18, 2003: Message edited by: D Wang ]
[ November 18, 2003: Message edited by: D Wang ]
[ November 18, 2003: Message edited by: D Wang ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, if thread A does hasNext(), returns true, then thread B does a remove() on that next element, thread A might use next() and get a NullPointerException (if it didn't throw a ConcurrentModificationException instead). Or A might get a reference to the element that was just removed, but when it tries to continue to the next element after that, it gets a NPE. If thread B had added a new element rather than removine one, you still can get weird results, because adding an element is not an atomic operation. E.g. thread A might access the element being added before the add operation is complete, which means that maybe next() works OK but previous() (from ListIterator) does not. I can get very confusing. Most of the things that can go wrong are relatively unlikely, but that's often a bad thing. You might have code that works fine 99% of the time, then failys mysteriously - and there's no way for you to reliably reproduce the problem to figure out what's going on. This is very difficult to debug. The ConcurrentModificationException is an attempt to detect bad programming practices as early as possible, and force you to fix them, rather than waiting until later when something goes wrong and you have no idea what happened.
 
Ricky Wang
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Yingst:

Thanks a lot for your illustration.
This mechanism seems to comprise with performance. Well, if I have a lot of elements(may be thousands of) within a LinkedList for iterating, it means that no other threads can update this LinkedList.
How should I improve the performance without comprising consistency?
 
Dana Hanna
Ranch Hand
Posts: 227
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Consider making a soft copy of the list. The LinkedList object implements Cloneable, and it does a soft copy. Thus, there is a new list, pointing at the same objects as the original, but it can be used exclusively.
With this approach, you'd just synch. the call to clone().

Beautiful!
 
Mr. C Lamont Gilbert
Ranch Hand
Posts: 1170
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Its worse than that Joe. Now your other iterator thinks their are more objects left than their actually are. Now you get a null pointer exception or an ArrayIndexOutOfBounds exception.
 
Billy Tsai
Ranch Hand
Posts: 1306
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In a multi-threaded scenario where concurrent access occurs, can the Iterator.remove() method still be used even if the Iterator object is declared as a local variable and is derived from calling iterator() on a java.util.List that is also created as a local variable within the same method?
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!