I have next code in background thread
private List<IStartAction> mActions = Collections.synchronizedList(new ArrayList<IStartAction>());
protected void removeNonApplicableActions() {
Iterator<IStartAction> iterator = mActions.iterator();
while (iterator.hasNext()) {
IStartAction action = iterator.next();
if (!action.isApplicable()) {
iterator.remove();
}
}
}
When i run this in main thread got ConcurrentModificationException into iterator.next(). Why is this happening? I use thread-safe collection and remove items through iterator. Collection used in only this thread.
Thread safety for a synchronized collection only applies to one method call. Between method calls the lock is released and another thread can lock the collection. If you perform two operations, anything could happen in the meantime, unless you lock it your self. e.g.
// to add two elements in a row, you must hold the lock.
synchronized(mAction) {
mAction.add(x);
// without holding the lock, anything could happen in between
mAction.add(y);
}
Similarly to iterate over a synchronized collection, you have to hold the lock, otherwise anything could happen between method calls to the iterator.
synchronized (mAction) {
for(Iterator<IStartAction> iter = mActions.iterator(); iter.hashNext();) {
IStartAction action = iter.next();
if (!action.isApplicable()) {
iter.remove();
}
}
}