I'm using Vector instead of ArrayList to make a list safe in multi-threaded enviroment. But I keep getting ConcurrentModificationException when I trying to add items to the Vector while iterating it. Why is that and how can I prevent it?
 
    
    - 3,707
- 6
- 23
- 28
- 
                    2concurrent != parallel. You can get a ConcurrentModificationException with a single thread. – John Vint Mar 15 '13 at 16:58
3 Answers
You cannot modify a Vector while iterating over it. Store the items to add in a separate vector, and move them to the Vector when the loop is finished or loop over a copy of the original Vector.
ADDED: To get a mutex around the Vector in java, do this in both functions:
synchronized (list) {
  // modifying list
}
and:
synchronized (list) {
  // iterating over list
}
Of course I've assumed that the list is named list
 
    
    - 6,483
- 3
- 35
- 45
- 
                    4
- 
                    
- 
                    1You can _never_ modify the list while iterating over it. Even in single threaded programs. Modifying the underlying list invalidates the iterator. – fredrik Mar 15 '13 at 16:56
- 
                    
- 
                    None. It only synchronizes direct modifications and reads of the list. Which, in at least Java, does not include Iterators of the list. You need to use a mutex instead - locked for the entire duration of the loop, and which is locked while any other operation is performed on the list. – fredrik Mar 15 '13 at 16:58
- 
                    To prevent another thread from modifying the current thread's view of the list. Note that this does not imply the list is immutable. – Peter Bratton Mar 15 '13 at 16:58
- 
                    "*Store the items to add in a separate vector, and move them to the Vector when the loop is finished or loop over a copy of the original Vector.*" => or use an existing class of the standard JDK which does exactly that: a CopyOnWriteArrayList – assylias Mar 15 '13 at 17:00
- 
                    1@assylias That is not what that class does. It copies the list, throwing away the old one. What I propose is to wait with appending new items until the iterator finished. – fredrik Mar 15 '13 at 17:04
- 
                    I have one method that adds items to the Vector, and another method itareting on the Vector. I synchronized both, is that good idea? – Shelef Mar 15 '13 at 17:11
- 
                    Synchronizing methods will not help - as it only prevents that function from being run concurrently. It does not help with two different functions, they can still be executed concurrently – fredrik Mar 15 '13 at 17:13
- 
                    There is also recommended to declare synchronizing object as final, to sure that it's reference should be changed. – bgplaya Aug 14 '14 at 15:40
if you want to add items as you iterate, you'll want to use a ListIterator. by using Vector, you're not bypassing this rule (obviously), so I would recommend using the ArrayList instead.
 
    
    - 43,520
- 33
- 120
- 170
- 
                    I don't think it is safe to add while iterating with a ListIterator if more than one thread is involved. – assylias Mar 15 '13 at 16:58
- 
                    1@assylias, I misunderstood the question, I suppose. I was just addressing the `ConcurrentModificationException`. – mre Mar 16 '13 at 01:10
If you need to iterate and add concurrently to your list, you should use a concurrent list, such as CopyOnWriteArrayList. Note that if you write a lot to the list it will not be very efficient.
Otherwise, if you use a Vector or a synchronizedList, you need to hold the list's lock while iterating. That will prevent the exception but it will also prevent concurrency...
 
    
    - 321,522
- 82
- 660
- 783