2014-01-12 97 views
0

我需要帮助,这种情况如下: 我有2个方法:Java错误并发修改异常

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); 
    } 
} 

,并在方法calculatime第二种方法

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循环我只是得到第一个项目的结果,之后我得到了与标题相同的错误。请帮我解释一下这个案例。

+0

是这是一个单线程还是多线程应用程序?请给出例外的StackTrace。 –

+0

这里的错误:processList = parse(item,DEFAULT_START_LEVEL); –

+0

此刻的我是尝试使用的ListIterator –

回答

2

此异常的名称有点令人困惑,因为它与多线程无关。

会发生什么情况是您正在迭代正在迭代的正在修改的集合。

如果性能不是您最关心的问题,那么简单的出路就是复制列表并遍历该副本并将项目添加到原始列表中。

+0

这也是我的想法,但我在代码中找不到。 –

+0

你可以发布整个堆栈跟踪吗?在引发ConcurrentModEx的时候,你知道它已经完成了哪一行代码,然后你可以看到你的哪个java结构在那里被使用。 – pveentjer

+0

虽然名称很混乱,但它可能与多线程相关,因为当另一个线程修改您重复使用的集合时,异常也会发生。 – zapl

0

我的猜测是它涉及到recordList.subList()

返回此列表的部分视图。 [..]返回的列表由此列表支持。 [..]如果支持列表(即,此列表)在结构上以非返回列表以外的其他方式进行了修改,则此方法返回的列表的语义变得未定义。 [..]所有方法首先检查后台列表的实际modCount是否等于其预期值,如果不是,则抛出一个ConcurrentModificationException

我没有看到任何修改,所以它可能发生在findProcess()。考虑创建一个列表的副本:

new ArrayList(recordList.subList()) 
+0

感谢马库斯,我会检查这一点。 –

0

你得到,因为这种异常:

for (LogRecord record : recordList) { 
     if (record.isStartPoint()){ 
      recordList.remove(record); <--- This is the cause 
      return record; 
     } 
} 

使用一个迭代器,而非

Iterator<LogRecord> iterator = recordList.iterator(); 
while(iterator.hasNext()){ 
    LogRecord logRecord = iterator.next(); 
    if(record.isStartPoint()){ 
     iterator.remove(); 
     return logRecord; 
    } 

检查,如果这个工程

+0

我试试这个。但仍然是同样的错误 –