views:

265

answers:

5

This code will throw Concurrent Modification Exception if the list is modified in doSomething(). Is it possible to avoid it by enclosing the code in some synchronized block?

List l = Collections.synchronizedList(new ArrayList());

// normal iteration -- can throw ConcurrentModificationException
// may require external synchronization
for (Iterator i=list.iterator(); i.hasNext(); ) {
  doSomething(i.next());
}
A: 

You cannot modify it while you are iterating over it. Synchronizing won't help here.

EDIT : I forgot iterator does have the remove method. So it is possible to remove.

fastcodejava
+6  A: 
  • if you are removing an item from the list, you can do it by calling iterator.remove() instead of list.remove(iterator.next())

  • if you are adding an item - well, create a copy of the iterated list and add it there

  • if the code snippet above is part of the same method, then you don't need a synchronized list or synchronized blocks - no other thread can access the local list.

Bozho
+3  A: 

You can modify a Collection while iterating over it if you do so through the Iterator interface. You can use Iterator.remove() to remove elements.

Asaph
What i want to know is whether the ConcurrentModificationException can be prevented by putting the code in some synchronized blockhttp://www.ibm.com/developerworks/java/library/j-jtp07233.htmlThis link talks about synchronizing the iteration code in a synchronized block to prevent concurrent modification exception.
java_geek
A: 

I agree with others about Iterator and remove().


About synchronization, I wanted to add that synchronization is designed to control interactions between different threads.

It is typical for an object to have several methods synchronized, and that one would call another. So the language designers decided that the same thread would not be blocked by himself on a synchronized.

Also, thinking about it, it a thread is blocked waiting for himself, you have a magnificent starvation perspective! ;-)

So this answers one of your questions: it is not possible to avoid the problem by synchronizing your code.

KLE
A: 

Use CopyOnWriteArrayList instead of synchronized Array List

nanda