Java 迭代器中的ConcurrentModificationException.next()

Java 迭代器中的ConcurrentModificationException.next(),java,multithreading,java.util.concurrent,Java,Multithreading,Java.util.concurrent,我在后台线程中有下一个代码 private List<IStartAction> mActions = Collections.synchronizedList(new ArrayList<IStartAction>()); protected void removeNonApplicableActions() { Iterator<IStartAction> iterator = mActions.iterator();

我在后台线程中有下一个代码

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();
            }
        }
    }
private List mActions=Collections.synchronizedList(new ArrayList());
受保护的void removeNonApplicableActions(){
迭代器迭代器=mActions.Iterator();
while(iterator.hasNext()){
IStarAction action=iterator.next();
如果(!action.isapplicatable()){
iterator.remove();
}
}
}
当我在主线程中运行此命令时,ConcurrentModificationException进入迭代器。next()。
为什么会这样?我使用线程安全集合,并通过迭代器删除项。集合仅在此线程中使用。

同步集合的线程安全性仅适用于一个方法调用。在方法调用之间释放锁,另一个线程可以锁定集合。如果您执行两个操作,任何事情都可能同时发生,除非您自己将其锁定。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);
}
与对同步集合进行迭代类似,您必须持有锁,否则在对迭代器的方法调用之间可能会发生任何事情

synchronized (mAction) {
    for(Iterator<IStartAction> iter = mActions.iterator(); iter.hashNext();) {
        IStartAction action = iter.next();
        if (!action.isApplicable()) {
            iter.remove();
        }
    }
}
synchronized(mAction){
for(迭代器iter=mActions.Iterator();iter.hashNext();){
IStarAction action=iter.next();
如果(!action.isapplicatable()){
iter.remove();
}
}
}

synchronized意味着您可以在特定条件下在多个线程中修改列表(请参阅javadoc中的synchronizedList()方法)。这里有一个不同的问题,您正在同时迭代和删除。请使用listIterator而不是普通迭代器。使用listIterator()方法。能否提供一个代码的最小工作示例,以便我们重现问题?
ConcurrentModificationException
不一定表示有多个线程在修改列表,这是因为您正在同时迭代列表并同时修改它。这看起来很奇怪/有问题。请注意。
isapplicatable()
做什么?它是否以任何方式修改了
mActions