Я использую многопоточность для обработки списка строк партиями, однако я получаю эту ошибку, когда задача Runnable выполняет итерацию по списку для обработки каждой строки.java.util.ConcurrentModificationException: Неожиданное изменение списка при многопоточности?
Например, код примерно следующим образом этой структуры:
public class RunnableTask implements Runnable {
private List<String> batch;
RunnableTask(List<String> batch){
this.batch = batch;
}
@Override
public void run() {
for(String record : batch){
entry = record.split(",");
m = regex.matcher(entry[7]);
if (m.find() && m.group(3) != null){
currentKey = m.group(3).trim();
currentValue = Integer.parseInt(entry[4]);
if (resultMap.get(currentKey) == null){
resultMap.put(currentKey, currentValue);
} else {
resultMap.put(currentKey, resultMap.get(currentKey) + currentValue);
}
}
}
}
}
В случае, если поток, который проходит эту партию для обработки никогда не изменяет «партии» и никаких изменений в партию сделана внутри для цикла. Я понимаю, что это исключение ConcurrentModificationException связано с изменением List во время итерации, но насколько я могу судить, этого не происходит. Есть что-то, что мне не хватает?
Любая помощь приветствуется,
Thankyou!
UPDATE1: Кажется, что переменные-экземпляры не являются потокобезопасными. Я попытался использовать CopyOnWriteArrayList вместо ArrayList, но получил непоследовательные результаты - предположив, что полная итерация не завершится до того, как список каким-то образом изменен, а не каждый элемент обрабатывается.
UPDATE2: Блокировка на петле с синхронизированным и/или реентронным замком по-прежнему дает то же исключение.
Мне нужен способ передачи списков запускаемым задачам и перебора этих списков без новых потоков, вызывающих проблемы параллелизма с этим списком.
Учитывая, что вы не показываете код внутри цикла foreach, никто не может сказать. Кроме того, ваш список изменен _outside_ из runnable? – fge
Ставлю пиво, которое либо вызывающий, либо ваш цикл изменяет партию. – user949300
Обработка внутри цикла использует только запись и не ссылается на пакет. – ddnm