Java并行流只使用一个线程?
我正在使用最新的
Java 8 lambdas和并行流来处理数据.
我的代码如下: ForkJoinPool forkJoinPool = new ForkJoinPool(10); List<String> files = Arrays.asList(new String[]{"1.txt"}); List<String> result = forkJoinPool.submit(() -> files.stream().parallel() .flatMap(x -> stage1(x)) //at this stage we add more elements to the stream .map(x -> stage2(x)) .map(x -> stage3(x)) .collect(Collectors.toList()) ).get(); 流以一个元素开始,但在第二个阶段添加更多元素. 如果我从2个元素开始(即我将第二个元素添加到初始列表中),则会产生2个线程来处理流等等……如果我没有将流显式提交给ForkJoinPool,也会发生这种情况. 问题是:它是记录在案的行为还是可能在实施中发生变化?有没有办法控制这种行为,并允许更多的线程,无论初始列表? 解决方法
您观察的是特定于实现的行为,而不是指定的行为.
当前的JDK 8实现查看最外层流的Spliterator,并将其用作拆分并行工作负载的基础.由于该示例在原始源流中只有一个元素,因此无法拆分,并且该流运行单线程.这适用于常见(但绝不仅限于)flatMap返回零,一个或仅少数元素的情况,但在返回大量元素的情况下,它们都是按顺序处理的.实际上,flatMap函数返回的流被强制进入顺序模式.见ReferencePipeline.java第270行. “显而易见”的事情是使这个流并行,或者至少不强制它是顺序的.这可能会也可能不会改善.最有可能的是它会改善一些事情,但会使其他事情变得更糟.这里肯定要求更好的政策,但我不确定它会是什么样子. 另请注意,用于强制并行流在您选择的fork-join池中运行的技术,通过向其提交运行管道的任务,也是特定于实现的行为.它在JDK 8中以这种方式工作,但它可能在将来发生变化. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |