繁体   English   中英

在Java中使用addAll over Set的ConcurrentModification异常

[英]ConcurrentModification exception using addAll over Set in Java

我对Java应用程序中遇到的一个问题感到完全困惑。

当我尝试运行下面给出的代码时,Java在“ if(this.vertexStore.get(v).addAll(output))”行上引发ConcurrentModificationException。

考虑到这是一个完全单线程的应用程序,我发现这很奇怪,而且我实际上并没有修改我所知道的循环的任何内容?

实际上,我唯一能看到发生错误的地方是在addAll方法内部,但这也不应该发生,因为我正在使用Java类库中的HashMap和LinkedList ...

private Queue<Vertex> worklist = new LinkedList<Vertex> ( );
protected Map<Vertex, Set<T>> vertexStore = new HashMap<Vertex, Set<T>> ( );

// . . .

while ( this.worklist.size ( ) > 0 ) {
        Vertex vertex = this.worklist.remove ( );

        Set<T> output = this.processVertice ( vertex, this.vertexStore.get ( vertex ) );

        this.vertexStore.put ( vertex, output );

        for ( Vertex v : vertex.edgesTo ( ) ) {
            // Conveniently, addAll returns true if the set changed
            if ( this.vertexStore.get ( v ).addAll ( output ) )
                this.worklist.add ( v );
        }
    }

编辑:错误跟踪:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
    at java.util.HashMap$KeyIterator.next(HashMap.java:828)
    at java.util.AbstractCollection.addAll(AbstractCollection.java:305)
    at DataFlowAnalyser.process(DataFlowAnalyser.java:41) (the if line)

任何好的想法都非常欢迎!

PS: 此处提供完整源代码(抱歉,缺少注释,代码未完成)

干杯,乔恩

您正在调用addAll并传递对Set本身的引用。 如果通过代码调试,您将看到this.vertexStore.get(v)返回与输出var引用的对象相同的对象。

通常,对于HashSet来说这不是问题,因为如果您只是添加所有相同的元素,则addAll实际上不会修改HashSet的状态。 但是,在这种情况下,您要在将HamiltonPath实例添加到集合中之后对其进行修改,这又会更改其哈希码,并使HashSet认为要添加的对象与现有对象不同。

这是一些比我的散文更好地说明问题的代码:

List<String> list1 = Arrays.asList("foo");
List<String> list2 = Arrays.asList("bar");
Set<List<String>> set = new HashSet<List<String>>();
set.add(list1);
set.add(list2);
list1.add("baz"); 
list2.add("qux");
set.addAll(set); // throws ConcurrentModificationException

您的代码中断,因为您在迭代一个集合时正在修改它,而Java不喜欢它。 如果要执行此操作,请使用ConcurrentHashMap,它使用与标准映射不同的迭代器类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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