Java并发修改异常(枚举器)

时间:2019-03-13 09:39:38

标签: java

此源代码有问题。 外部for循环不会迭代:

java.util.ConcurrentModificationException 
     at java.util.Hashtable$Enumerator.next(Hashtable.java:1387)
    

Foo函数仅从myVar读取并返回一个Hashtable。

为了不重写myVar函数,我创建了一个名为iteratingHashTable的辅助变量。

while (condition) {

    Hashtable<String, Boolean> iteratingHashTable = new Hashtable<String, Boolean>();

    iteratingHashTable = myVar;

    for (Map.Entry entry : iteratingHashTable.entrySet()) {

        if (value.equals(entry.getValue())) {
            String analyzingURL = entry.getKey().toString();
            myVar.replace(analyzingURL, true);

            Hashtable<String, Boolean> listedLinks = Foo(myVar, entry.getKey().toString());

            if (listedLinks != null) {

                for (Map.Entry entry1 : listedLinks.entrySet()) {

                    if (!entry1.getKey().toString().isEmpty()) {
                        myVar.put(entry1.getKey().toString(), entry1.getValue().equals(true));
                    }
                }
            }
        } else {
            condition = false;
        }
    }
}

3 个答案:

答案 0 :(得分:1)

我认为,但我不确定:

iteratingHashTable = myVar;

引用相同的对象,因此,在下面的代码中,当您尝试将myVariteratingHashTable用于不同的操作时,您总是在使用同一对象。

答案 1 :(得分:1)

如果在创建迭代器之后的任何时候都对Hashtable进行结构修改,则除了通过迭代器自己的remove方法之外,该迭代器将以任何其他方式抛出ConcurrentModificationException。

在使用普通集合类(而不是并发集合类)时,不允许在for循环中的列表上进行任何修改。由于快速失败行为。这意味着,如果对同一列表或映射进行任何修改,则在迭代集合的项目时,它将引发current并发的ModificationException。

要解决上述问题,请使用并发HashMap或再创建一个hashMap并在该映射中添加或替换这些元素,并在for循环完成后将这些元素添加到原始映射中。

答案 2 :(得分:0)

  • Java集合类是快速失败的,这意味着如果在某个线程正在遍历集合时更改了集合,则iterator.next()将抛出ConcurrentModificationException。

  • 在您的情况下,您正在迭代哈希表并更改该哈希表的值,因此会引发此异常。当您分配iteratingHashTable = myVar;两个变量都指向相同。

  • 您可以通过以下方式避免此异常:

    1)如果使用> = JDK1.5,则可以使用ConcurrentHashMap和CopyOnWriteArrayList(推荐方法)

    2)您可以在迭代时使用同步块来锁定表。

相关问题