Параллельный поток после обновления коллекции - PullRequest
0 голосов
/ 15 февраля 2019

Я делаю код совместимым с OpenJDk8 и заметил, что иногда следующие фрагменты генерируют ConcurrentModificationException.

Код выполняется в одном потоке.

list = new ArrayList<>();

list.addAll(newElements);
list.stream().parallel().forEach(o -> {});

Исключение выдается ForkJoin, когда потоки потока разделяют потоксписок между ними.Через некоторое время я подумал, что это разумное поведение по умолчанию (не синхронизировано, простая коллекция) потоковые потоки не являются новыми, и они использовали из пула (они могли видеть список в несогласованном состоянии), но копирование коллекции перед повторением не выглядело бы неплохо.

Я не нашел ошибку, связанную с этим, поэтому я задаю вопрос, что модель памяти Java думает об этом случае?

Кстати, чтобы сообщить об ошибке OJDK, вы должны быть разработчиком.


java.util.ConcurrentModificationException: java.util.ConcurrentModificationException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:593)
    at java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:677)
    at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:735)
    at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:174)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
    at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:583)
    at scheduler.JobScheduleUpdater.fetchJobSchedules(JobScheduleUpdater.java:118)
    at scheduler.JobScheduleUpdater.processOneUpdate(JobScheduleUpdater.java:102)
    at 
scheduler.JobScheduleUpdater.execute(JobScheduleUpdater.java:81)
    at scheduler.JobScheduleUpdater$$EnhancerByMockitoWithCGLIB$$ccd35a20.CGLIB$execute$11(<generated>)
    at scheduler.JobScheduleUpdater$$EnhancerByMockitoWithCGLIB$$ccd35a20$$FastClassByMockitoWithCGLIB$$bf9de679.invoke(<generated>)
    at org.mockito.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:216)
    at org.powermock.api.mockito.repackaged.DelegatingMockitoMethodProxy.invokeSuper(DelegatingMockitoMethodProxy.java:20)
    at org.mockito.internal.invocation.realmethod.DefaultRealMethod.invoke(DefaultRealMethod.java:21)
    at org.mockito.internal.invocation.realmethod.CleanTraceRealMethod.invoke(CleanTraceRealMethod.java:30)
    at org.mockito.internal.invocation.InvocationImpl.callRealMethod(InvocationImpl.java:112)
    at org.mockito.internal.stubbing.answers.CallsRealMethods.answer(CallsRealMethods.java:41)
    at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:93)
    at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:29)
    at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:38)
    at org.powermock.api.mockito.repackaged.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:60)
    at scheduler.JobScheduleUpdater$$EnhancerByMockitoWithCGLIB$$ccd35a20.execute(<generated>)
    at commons.util.service.ShutdownCapableThread.run(ShutdownCapableThread.java:74)
    at scheduler.JobScheduleUpdater$$EnhancerByMockitoWithCGLIB$$ccd35a20.CGLIB$run$15(<generated>)
    at scheduler.JobScheduleUpdater$$EnhancerByMockitoWithCGLIB$$ccd35a20$$FastClassByMockitoWithCGLIB$$bf9de679.invoke(<generated>)
    at org.mockito.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:216)
    at org.powermock.api.mockito.repackaged.DelegatingMockitoMethodProxy.invokeSuper(DelegatingMockitoMethodProxy.java:20)
    at org.mockito.internal.invocation.realmethod.DefaultRealMethod.invoke(DefaultRealMethod.java:21)
    at org.mockito.internal.invocation.realmethod.CleanTraceRealMethod.invoke(CleanTraceRealMethod.java:30)
    at org.mockito.internal.invocation.InvocationImpl.callRealMethod(InvocationImpl.java:112)
    at org.mockito.internal.stubbing.answers.CallsRealMethods.answer(CallsRealMethods.java:41)
    at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:93)
    at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:29)
    at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:38)
    at org.powermock.api.mockito.repackaged.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:60)
    at scheduler.JobScheduleUpdater$$EnhancerByMockitoWithCGLIB$$ccd35a20.run(<generated>)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.util.ConcurrentModificationException
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1388)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
    at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

1 Ответ

0 голосов
/ 15 февраля 2019

Код отлично работает в моем редакторе.ConcurrentModificationException срабатывает, когда вы изменяете что-то, над чем вы работаете.Не видя весь ваш код, я не думаю, что смогу решить проблему.

Пример ConcurrentModificationException:

List<Integer> integers = new ArrayList<>();

integers.add(12);
integers.add(11);
integers.add(1);



for (Integer integer : integers) {
   integers.remove(1);
}

Ресурс о том, как решить вашу проблему, может бытьнайдено здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...