从流切换到并行流时的空指针异常



帮助我理解这一点;我有一个基于流的逻辑,该逻辑根据从其字段构造的一些键字符串将实体分组到列表映射中。

使用流,运行没有任何错误:

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 方法中确实发生了 NullPointerException,但该异常被 ForkJoin 框架吞噬了,或者看起来是这样。它在初始堆栈跟踪中完全不可见;只有通过在buildKey中捕获运行时异常并打印它,我才能使其可见。(NPE 本身确实是由在不同线程上运行的代码引起的,该线程没有绑定一些与线程相关的数据。

最新更新