2014-01-12 5 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); 
    } 
} 

и второй метод

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

по методу calculatime в цикл я просто получить результат для первого элемента, и после этого я получил ошибку, то же самое название. пожалуйста, помогите мне и объясните мне больше для этого случая.

+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

Я пробую это. но по-прежнему такая же ошибка –

Смежные вопросы