简体   繁体   中英

ConcurrentModificationException in iterator.next()

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. eg

// 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();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM