[英]Java forEach lambda throws concurrentModificationException
What could be the reason that below method throws ConcurrentModificationException
? 以下方法引发
ConcurrentModificationException
的原因可能是什么?
static Set<String> setOfAllocAccountsIn(final @NotNull Execution execution) {
final Set<String> allocAccounts = new HashSet<>();
execution.legs().forEach(leg -> leg.allocs().forEach(alloc -> {
if (alloc.account() != null) {
allocAccounts.add(alloc.account());
}
}));
return allocAccounts;
}
Stack Trace: 堆栈跟踪:
"java.util.ConcurrentModificationException:
at java.base/java.util.ArrayList.forEach(ArrayList.java:1382)
at com.client.stp.util.DealsBuilderUtil.setOfAllocAccountsIn(DealsBuilderUtil.java:146)
at com.client.stp.builder.GridDealsObjectBuilder.build(GridDealsObjectBuilder.java:47)
at com.client.stp.processor.DealToPDXMLTransformer.transform(DealToPDXMLTransformer.java:29)
at com.client.stp.processor.WorkPartitionerEngine.lambda$onEventSubmit$0(WorkPartitionerEngine.java:40)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:514)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.base/java.lang.Thread.run(Thread.java:844)
With simple for-loop
it works fine. 使用简单的
for-loop
,即可正常工作。 The method is called by multiple threads with its own copy of execution object. 该方法由具有自己的执行对象副本的多个线程调用。
Solution which worked with simple for loop: 与简单的for循环一起使用的解决方案:
static Set<String> setOfAllocAccountsIn(final @NotNull Execution execution) {
final Set<String> allocAccounts = new HashSet<>();
for (final ExecutionLeg executionLeg : execution.legs()) {
for (final ExecutionAlloc executionAlloc : executionLeg.allocs()) {
if (executionAlloc.account() != null) {
allocAccounts.add(executionAlloc.account());
}
}
}
return allocAccounts;
}
I feel that it has something to do with static method and its local variable accessed by multiple threads but per theory that will be thread local variable and are not shared. 我觉得它与静态方法有关,它的局部变量可以被多个线程访问,但是从理论上讲,它将是线程局部变量并且不会共享。 Give me some time to put down some simple example.
给我一些时间写下一些简单的例子。
Your logic can be like this : 您的逻辑可以是这样的:
return execution.legs().stream()
.flatMap(leg -> leg.allocs().stream())
.map(executionAlloc -> executionAlloc.account())
.filter(Objects::nonNull)
.collect(Collectors.toSet());
forEach
inside forEach
(Here I replace it with flatMap
) forEach
内forEach
(在这里,我将其替换为flatMap
) alloc.account()
is null or not (I replace it with filter
) alloc.account()
是否为null(我用filter
替换它) collect
) collect
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.