【发布时间】:2018-01-24 08:25:57
【问题描述】:
帮助我理解这一点;我有一个基于流的逻辑,它根据由其字段构造的一些键字符串将实体分组到列表映射中。
使用流运行没有任何错误:
Map<String, List<Entity>> mapOfkeyToListOfEntities = baseJournalEntries
.stream()
.collect(Collectors.groupingBy(eneity -> buildKey(entity)));
但如果我尝试通过将 steam() 方法更改为 parallelStream() 来并行执行此操作,如下所示:
Map<String, List<Entity>> mapOfkeyToListOfEntities = baseJournalEntries
.parallelStream()
.collect(Collectors.groupingBy(entity -> buildKey(entity)));
我得到一个例外:
Caused by: java.lang.NullPointerException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.__newInstance(DelegatingConstructorAccessorImpl.java:45)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:598)
at java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:677)
at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:735)
at java.util.stream.ReduceOps$ReduceOp.evaluateParallel(ReduceOps.java:714)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
由于流版本有效,所有实体都能够生成密钥,因此 buildKey 中不能有 NPE...我不明白。我需要看哪里?
【问题讨论】:
-
我猜
buildKey()中存在并发错误。请提供minimal reproducible example。 -
enEity -> buildKey(entity)
-
您发布的堆栈跟踪表示在调用者线程中重新创建异常。此异常应该有另一个原因,原始异常的堆栈跟踪将显示原始异常发生的位置。
-
可能修复也可能不修复。如果没有 buildKey 的来源和它调用的函数,这是不可能的答案。你能给出包含 buildKey 的类的来源吗?
-
为什么不知道
buildKey做了什么以及为什么会失败。将其设为synchronized可确保不会同时调用它,但如果假设它以特定顺序与流元素一起调用,它仍然可能会失败。
标签: java parallel-processing nullpointerexception java-stream