当前位置: 首页 > 知识库问答 >
问题:

Java错误并发修改异常

夏侯朝斑
2023-03-14

下面我需要帮助:我有两种方法:

private void calculateTime(Map.Entry<List<String>, List<LogRecord>> entry, List<LogProcess> processList) {
    List<List<LogRecord>> processSpentTime = new ArrayList<List<LogRecord>>();
    processSpentTime = subListProcess(entry, processSpentTime);
    for (List<LogRecord> item : processSpentTime) {
        processList = parse(item, DEFAULT_START_LEVEL);
    }
}

第二种方法

private List<LogProcess> parse(List<LogRecord> recordList, int level) {
    List<LogProcess> processList = new ArrayList<LogProcess>();
    if(!recordList.isEmpty()) {
        LogProcess process = findProcess(recordList, level);
        if(!(process instanceof NullLogProcess)) {
            if(!(process instanceof IncompleteLogProcess)) {
                processList.add(process);
            }

            int fromIndex = recordList.indexOf(process.returnStartIndexOfNextProcess()) + 1;
            processList.addAll(parse(recordList.subList(fromIndex, recordList.size()), level));
        }
    }
    return processList;
}

public LogProcess findProcess(List<LogRecord> recordList, int level) {
    LogRecord endRecord = null;
    LogRecord startRecord = findStartRecord(recordList);
    if(startRecord instanceof NullLogRecord) {
        return new NullLogProcess();
    }       

    List<LogRecord> startEndRecord = findStartEndRecord(startRecord, recordList);
    startRecord = startEndRecord.get(0);
    endRecord = startEndRecord.get(1);

    LogProcess process = returnLogProcess(startRecord, endRecord);
    process.setLevel(level);
    process.setChildren(findChildProcess(recordList, startRecord, endRecord, level + 1));

    return process;
}

private List<LogProcess> findChildProcess(List<LogRecord> recordList, LogRecord startRecord, LogRecord endRecord, int level) {
    int fromIndex = recordList.indexOf(startRecord) + 1;
    int toIndex = recordList.indexOf(endRecord);
    if(toIndex > fromIndex) {
        List<LogRecord> recordSubList = recordList.subList(fromIndex, toIndex);
        return parse(recordSubList, level);
    } else  {
        return new ArrayList<LogProcess>();
    }
}

private List<LogRecord> findStartEndRecord(LogRecord startRecord, List<LogRecord> recordList) {
    List<LogRecord> startEndRecord = new ArrayList<LogRecord>();
    if (!recordList.isEmpty()) {
        startEndRecord.add(startRecord);
        for (LogRecord record : recordList) {

            boolean isStartRecord = record.isStartPoint() && record.hasSameActionName(startRecord);
            if(isStartRecord){
                startEndRecord = new ArrayList<LogRecord>();;
                startEndRecord.add(record);
                continue;
            }

            boolean isEndRecord = record.isEndPoint() && record.hasSameActionName(startRecord);
            if (isEndRecord) {
                startEndRecord.add(record);
                return startEndRecord;
            }

        }
        return startEndRecord;
    }
    return startEndRecord;
}

private LogRecord findStartRecord(List<LogRecord> recordList) {
    for (LogRecord record : recordList) {
        if (record.isStartPoint()){
            recordList.remove(record);
            return record;
        }
    }
    return new NullLogRecord();
}

for循环中的方法calculatime中,我只得到第一个项目的结果,然后得到与标题相同的错误。请帮帮我,为这个案子多解释一下。

共有2个答案

潘飞英
2023-03-14

我猜测它与recordlist.sublist():

返回此列表部分的视图。[..]返回的列表由此列表支持。[..]如果备份列表(即此列表)以任何方式而不是通过返回的列表进行结构修改,则此方法返回的列表的语义将变得未定义。[..]所有方法首先检查备份列表的实际modCount是否等于其期望值,如果不等于,则抛出ConcurrentModificationException

我没有看到任何修改,所以它很可能发生在findprocess()中。请考虑创建该列表的副本:

new ArrayList(recordList.subList())
董霖
2023-03-14

这个异常的名称有点混乱,因为它与多线程无关。

所发生的情况是,您在迭代一个集合时,该集合正在被修改。

如果性能不是您最关心的问题,那么一个简单的解决方法就是复制列表,然后迭代该副本并将项添加到原始列表中。

 类似资料:
  • 问题内容: 我正在为我的大学课程使用一些代码,并从 至: 但是新方法不断给出并发修改错误。我如何解决这个问题,为什么会发生呢? 问题答案: 这是因为执行后您继续遍历该列表。 您正在同时读取和写入列表,这破坏了foreach循环下面的迭代器协定。 用 描述如下: 返回迭代中的下一个元素。 如果迭代没有更多元素,则抛出该异常。 您可以用来检查下一个元素是否可用。

  • 问题内容: 我有这段代码,它给了我并发修改异常。即使看不到任何并发修改,我也无法理解为什么继续得到它。 问题答案: 为了避免,你应该这样编写代码: 允许你在迭代期间修改列表,但不能在创建和使用列表之间进行修改。

  • 问题内容: 问题发生在 包含该行的代码位于 所有这一切都在里面,这里是一个 当我触摸时,它可能会激活,这将创建另一个具有不同属性的属性,这些属性会从屏幕上掉下来并在不到一秒钟的时间内销毁自己。这是我创建粒子效果的方式。我们可以将其称为“粒子” ,就像构造函数中的参数一样。 一切正常,直到我添加另一个main为止。现在,我同时在屏幕上有两个,如果我触摸最新的,它可以正常工作并启动粒子。 但是,如果我

  • 问题内容: 您能否告诉我在单线程环境中是否有可能发生并发修改异常的方法,我下面发布的以下应用程序由两个线程组成,请告诉我我也可以在单个线程中看到相同的异常..请劝告 是的,我知道,在单线程环境中,此错误可能会出现..如下面的代码所示。 请告知解决该问题的方法是什么..这样就不会出现此错误.. !! 问题答案: 可以在单线程环境中引发A。只要在不应该​​在上下文中修改对象的情况下使用它,就不必在另一

  • 当Maven构建我的项目并运行单元测试时,有时会抛出一个并发修改异常(大约5次中有1次会失败,其他时间会成功构建)。但是当我以单元测试的形式在本地运行测试时,它们都会毫无例外地通过。 在我的pom.xml文件我有Surefire插件配置为: 然而,我得到的stackTrace没有提到是什么导致了并发修改异常。 我注意到所有的测试都通过了构建,但是出于某种原因,Maven重新打印了已经通过但现在有测

  • 另一方面,如果我们这样写,就没有并发修改异常!注意,代码完全相同,除了用于比较的字符串,在第一个示例中是代码,在第二个示例中是Java 我使用的是Netbeans 8.2,Windows 7 32bit,JDK 1.8.0_131有什么问题吗?