java .lang.ArrayIndexOutOfBoundsException: при использовании параллельного потока для добавления элементов в список - PullRequest
3 голосов
/ 02 марта 2020

Я работаю, чтобы оптимизировать некоторую обработку файла CSV, поэтому пытаюсь ускорить реализацию Джексона. Итак, у меня есть:

List<T> testResults=new ArrayList();
Stream<T> testStream= Streams.stream(TestIterator);
testStream.parallel().forEach(p->testResults.add(p));

и вот я получаю:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 360145
at java.util.ArrayList.add(Unknown Source)
at xml_test.opencsv.App.lambda$1(App.java:85)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.ForEachOps$ForEachTask.compute(Unknown Source)
at java.util.concurrent.CountedCompleter.exec(Unknown Source)
at java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
at java.util.concurrent.ForkJoinTask.doInvoke(Unknown Source)
at java.util.concurrent.ForkJoinTask.invoke(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(Unkno

Есть идеи, что происходит? Если я уберу «параллель», он будет работать, но очень медленно.

1 Ответ

5 голосов
/ 02 марта 2020

ArrayList не является поточно-ориентированной реализацией. Одно из решений состоит в том, чтобы заключить его в Collections.synchronizedList():

Возвращает синхронизированный (потокобезопасный) список, поддерживаемый указанным списком.

List<T> testResults = Collections.synchronizedList(new ArrayList<>());
...