aspose file tools
The moose likes Java in General and the fly likes Multiple users of a HashMap / Iterator - Handling Synchronization Big Moose Saloon
  Search | Java FAQ | Recent Topics
Register / Login


JavaRanch » Java Forums » Java » Java in General
Reply Bookmark "Multiple users of a HashMap / Iterator - Handling Synchronization" Watch "Multiple users of a HashMap / Iterator - Handling Synchronization" New topic
Author

Multiple users of a HashMap / Iterator - Handling Synchronization

Jim Plunkett
Greenhorn

Joined: Aug 23, 2001
Posts: 9
I have a multi-process situation which I need help understanding how the Java engine works.
One process will be polling another system for information and generating and maintaining a collection of active objects (probably in a HashMap). At any time new objects (HashMap Entries) may be added and/or old objects deleted.
Simultaneously, another process will be iterating across these objects, using them as a basis to perform work (probably using an Iterator). I expect the main loop will awake, initialize an iterator, and then work down the list of objects.
Now, how much of this is handled by Java itself, and what needs to be synchronized? Will the iterator's list be updated as HashMap entries are added and removed? Do I have to check for the (continued) existence of each object at each iter.next() call? Will the thing crash if iter.next() refers to a (recently) removed entry?
Is there some other approach that I should be using?
Thanks In Advance...
Jim!
Roy Ben Ami
Ranch Hand

Joined: Jan 13, 2002
Posts: 732
you are not allowed to change a collection (add or remove) when you iterate over it. this will cause an error and unpredictable result.
check the API , it clearly says that while iterating over a collection YOU need to check that the collection doesnt change.
so you will need to synchornize the iteration as well as the parts that access the collection you have.
John Smith
Ranch Hand

Joined: Jul 20, 2001
Posts: 84
I think you should be fine if you do the following:

If you're iterating over your map (using an iterator) and the map changes in any way, a ConcurrentModificationException will be thrown...
Randy
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18670
But Randy, that's the problem - he does want to iterate over the collection while it's being modified. The ConcurrentModificationException is great for debugging purposes in that it helps identify the cause of problems - but it's not something we'd want to see in most finished applications. Roy's advice works - if you synchonrize over the whole iteration in addition to the individual method calls, you're safe. The individual methods can be synchronized using Collections.synchronizedMap(), but that doesn't protect the iteration. You must sync that part explicitly.
Alternately, if the iteration is a lengthy process, it may well be desireable to allow other threads to put/get/remove while you're iterating. This can be accomplished by making a copy of the HashMap entries, and iterating over that rather than the original HashMap. You'll miss any objects added to the map after the copying - but you'll probably want to be re-running the iterator periodically anyway, so those objects will be picked up on the next time through the iterator. And the iterator may have some objects that have been removed from the map by the time you get around to processing them - if this is a problem, do a (synchronized) containsKey() just before processing the item, to see if it's still there. There's still a chance it could be removed immediately afterwards, and you could still end up processing an object after it's been removed. Depending on your application this could be a serious problem, or just a minor inefficiency. You can put in some more synchronization to avoid this. As long as you're exiting and rentering the sync block for each new iteration, other threads will have an opportunity to modify the map in between. Which is the whole point of this method - you want the other threads to not be completely blocked during the iteration.


"I'm not back." - Bill Harding, Twister
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
Jim is quite correct. In fact, that is the way that JavaBean objects handle event notification. Since it is possible that a listener can try to add itself to the event notification vector while the bean is iterating through the Vector to notify listeners of an event, the bean copies the Vector and then iterates through the copy.
Here's an example of some code I used in a bean I developed many years ago:

[ June 04, 2002: Message edited by: Thomas Paul ]

Associate Instructor - Hofstra University
Amazon Top 750 reviewer - Blog - Unresolved References - Book Review Blog
Jim Plunkett
Greenhorn

Joined: Aug 23, 2001
Posts: 9
THANKS TO ALL!
THESE RESPONSES ARE ENORMOUSLY HELPFUL! The various perspectives give me a much clearer picture of the issues.
Jim!
 
I agree. Here's the link: http://zeroturnaround.com/jrebel - it saves me about five hours per week
 
subject: Multiple users of a HashMap / Iterator - Handling Synchronization
 
Similar Threads
Why use Map.entrySet()
Why Groovy?
HashMap and database problem
Can't figure out the logic in this method
XML parsing large complex xml data