【问题标题】:Iterator but still ConcurrentModificationException迭代器但仍然是 ConcurrentModificationException
【发布时间】:2015-12-23 18:10:34
【问题描述】:

全部,

遇到 ConcurrentModificationException 问题并努力寻找解决方案,部分原因是我在迭代列表时看不到我在哪里修改列表...有什么想法吗?我已经突出显示了导致问题的行 (it3.remove())。真的在这个停滞不前..

编辑:堆栈跟踪:

Exception in thread "Thread-4" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at com.shimmerresearch.advancepc.InternalFrameAndPlotManager.subtractMaps(InternalFrameAndPlotManager.java:1621)

第 1621 行对应于我上面引用的代码中的 it3.remove()。

private void subtractMaps(ConcurrentSkipListMap<String, PlotDeviceDetails> firstMap, ConcurrentSkipListMap<String, PlotDeviceDetails> secondMap) {

    // iterate through the secondmap
    Iterator<Entry<String, PlotDeviceDetails>> it1 = secondMap.entrySet().iterator();
    while (it1.hasNext()) {
        Entry<String, PlotDeviceDetails> itEntry = (Entry) it1.next();
        String mapKey = (String) it1Entry.getKey();
        PlotDeviceDetails plotDeviceDetails = (PlotDeviceDetails)it1Entry.getValue();

        // if we find an entry that exists in the second map and not in the first map continue
        if(!firstMap.containsKey(mapKey)){
            continue;
        }

         // iterate through a list of channels belonging to the secondmap
        Iterator <PlotChannelDetails> it2 = plotDeviceDetails.mListOfPlotChannelDetails.iterator(); 
        while (it2.hasNext()) {
            PlotChannelDetails it2Entry = it2.next();

            // iterate through a list of channels belonging to the firstmap
            Iterator <PlotChannelDetails> it3 = firstMap.get(mapKey).mListOfPlotChannelDetails.iterator();
            innerloop:
            while(it3.hasNext()){
                // if a channel is common to both first map and second map, remove it from firstmap
                PlotChannelDetails it3Entry = it3.next();
                if(it3Entry.mChannelDetails.mObjectClusterName.equals(it2Entry.mChannelDetails.mObjectClusterName)){
                    it3.remove(); // this line is causing a concurrentModificationException
                    break innerloop;
                }
            }
        }
    }
}

【问题讨论】:

  • 请将完整的堆栈跟踪添加到您的问题中。堆栈跟踪还包含发生问题的确切行号,因此它可以帮助您在不猜测的情况下突出显示它。
  • 从使用适当的泛型开始,让您的代码更易于阅读。
  • @RealSkeptic 堆栈跟踪添加在编辑中.. 它确认抛出异常的行是 it3.remove()

标签: java arraylist iterator concurrentmodification concurrentskiplistmap


【解决方案1】:

plotDeviceDetails.mListOfPlotChannelDetails 和 firstMap.get(mapKey).mListOfPlotChannelDetails 引用 same 列表。

plotDeviceDetails 和firstMap.get(mapKey) 是否也引用了同一个对象,没有更多信息未知,但它们共享频道列表。

【讨论】:

  • 它们只是名称相同的列表..plotDeviceDetails.mListOfPlotChannelDetails 是 secondmap 的列表条目,其中 firstMap.get(mapKey).mListOfPlotChannelDetails 是 firstmap 的列表条目。它们不引用同一个对象,,
【解决方案2】:

堆栈跟踪显示mListOfPlotChannelDetails 是ArrayList,并且由于堆栈跟踪还显示错误来自it3.remove(),并且代码中没有任何内容可以导致该错误,那么您就是真正面临并发修改,即另一个线程更新了被it3迭代的ArrayList。

记住,ArrayList不支持并发多线程访问。

【讨论】:

    猜你喜欢
    • 2017-11-11
    • 1970-01-01
    • 2019-12-27
    • 2013-09-26
    • 2017-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    相关资源
    最近更新 更多