根据flatMap的结果使流平行

时间:2020-09-23 04:11:30

标签: java parallel-processing java-stream

考虑以下简单代码:

Stream.of(1)
  .flatMap(x -> IntStream.range(0, 1024).boxed())
  .parallel() // Moving this before flatMap has the same effect because it's just a property of the entire stream
  .forEach(x -> {
     System.out.println("Thread: " + Thread.currentThread().getName());
  });

很长时间以来,我认为Java即使在flatMap之后也可以对元素进行并行执行。但是上面的代码显示了所有的“ Thread:main”,这证明了我的想法是错误的。

flatMap之后使其平行的一种简单方法是收集然后再次流式传输:

Stream.of(1)
  .flatMap(x -> IntStream.range(0, 1024).boxed())
  .parallel() // Moving this before flatMap has the same effect because it's just a property of the entire stream
  .collect(Collectors.toList())
  .parallelStream()
  .forEach(x -> {
     System.out.println("Thread: " + Thread.currentThread().getName());
  });

我想知道是否有更好的方法,以及关于flatMap的设计选择,该选择只能在调用之前并行化流,而不能在调用之后并行化。

==========关于此问题的更多说明========

从某些答案看来,我的问题似乎没有完全传达出来。正如@Andreas所说,如果我从3个元素的Stream开始,则可能有3个线程在运行。

但是我的问题确实是:this post指出,Java Stream使用一个通用的ForkJoinPool,其默认大小等于内核数的一倍。现在假设我有64个内核,那么我希望上面的代码在flatMap之后会看到许多不同的线程,但是实际上,它只看到一个(在Andreas的情况下为3)。顺便说一句,我确实使用isParallel来观察流是并行的。

说实话,我并不是出于纯粹的学术兴趣问这个问题。我在一个项目中遇到了这个问题,该项目提出了用于转换数据集的一长串流操作。链从单个文件开始,并通过flatMap爆炸到许多元素。但是显然,在我的实验中,它不能完全利用我的计算机(具有64个内核),而仅使用一个内核(从对cpu使用情况的观察)。

3 个答案:

答案 0 :(得分:0)

我想知道flatMap的设计选择是仅在调用之前并行化流,而不在调用之后并行化。

您误会了。 flatMap之前和之后的所有步骤都是并行运行的,但是它只会在线程之间分割原始流。 flatMap操作然后由一个这样的线程处理,并且其流不会被拆分。

由于原始流仅包含1个元素,因此无法拆分,因此parallel不起作用。

尝试更改为Stream.of(1, 2, 3),您会看到forEachflatMap之后,实际上在3个不同的线程中运行。 / p>

答案 1 :(得分:0)

https://www.learnopencv.com/image-alignment-feature-based-using-opencv-c-python/指定:

对于任何给定的元素,可以在库选择的任何时间和线程中执行操作。

特别是,“执行调用线程上的所有操作”似乎是一个很好的广泛安全的实现。

请注意,您尝试并行化流并不会要求任何特定的并行性,但是您更有可能看到此效果:

IntStream.range(0, 1024).boxed()
  .parallel()
  .map(i -> "Thread: " + Thread.currentThread().getName())
  .forEach(System.out::println);

答案 2 :(得分:0)

对于像我这样迫切需要并行化 flatMap 并且需要一些实用解决方案的人,不仅仅是历史和理论。对于那些在并行化它们之前不考虑收集它们之间的所有项目的人。

我想出的最简单的解决方案是手动进行展平,基本上是将其替换为 map + reduce(Stream::concat)

我已经在另一个话题中回答了同样的问题,详情请见 https://stackoverflow.com/a/66386078/3606820

相关问题