我有要并行处理的元素的集合。当我使用时List
,并行性有效。但是,当我使用时Set
,它不会并行运行。
我写了一个代码样本来说明问题:
public static void main(String[] args) {
ParallelTest test = new ParallelTest();
List<Integer> list = Arrays.asList(1,2);
Set<Integer> set = new HashSet<>(list);
ForkJoinPool forkJoinPool = new ForkJoinPool(4);
System.out.println("set print");
try {
forkJoinPool.submit(() ->
set.parallelStream().forEach(test::print)
).get();
} catch (Exception e) {
return;
}
System.out.println("\n\nlist print");
try {
forkJoinPool.submit(() ->
list.parallelStream().forEach(test::print)
).get();
} catch (Exception e) {
return;
}
}
private void print(int i){
System.out.println("start: " + i);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
System.out.println("end: " + i);
}
这是我在Windows 7上获得的输出
set print
start: 1
end: 1
start: 2
end: 2
list print
start: 2
start: 1
end: 1
end: 2
我们可以看到中的第一个元素Set
必须在处理第二个元素之前完成。对于List
,第二个元素在第一个元素结束之前开始。
您能否告诉我是什么原因导致此问题,以及如何使用Set
集合避免发生此问题?
我可以重现您看到的行为,其中并行性与您指定的fork-join池并行性的并行性不匹配。将fork-
join池的并行度设置为10,并将集合中的元素数增加到50后,我看到基于列表的流的并行度仅上升到6,而基于集合的流的并行度从未超过2。
但是请注意,这种将任务提交给fork-join池以在该池中运行并行流的技术是一种“技巧”,并且 不能保证 能正常工作。实际上, 未指定
用于执行并行流的线程或线程池。默认情况下,使用公共的fork-join池,但是在不同的环境中,最终可能会使用不同的线程池。(请考虑应用程序服务器内的容器。)
在java.util.stream.AbstractTask类中,该LEAF_TARGET
字段确定完成的拆分数量,而拆分又确定了可以实现的并行数量。该字段的值基于ForkJoinPool.getCommonPoolParallelism()
哪个当然使用了公共池的并行性,而不取决于运行任务的任何池。
可以说这是一个错误(请参阅OpenJDK问题JDK-8190974),但是,整个区域都未指定。但是,系统的这一领域肯定需要发展,例如在拆分策略,可用并行性,处理阻塞任务等方面。JDK的未来版本可能会解决其中一些问题。
同时,可以通过使用系统属性来控制公共fork-join池的并行性。如果将此行添加到程序中,
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "10");
并且您在公共池中运行流(或者,如果将它们提交到具有足够高的并行性集的自己的池中),您会发现有更多的任务并行运行。
您也可以使用-D
选项在命令行上设置此属性。
同样,这不是保证的行为,将来可能会改变。但是在可预见的将来,该技术可能会对JDK 8实现有效。
更新2019-06-12:
JDK-8190974
错误已在JDK
10中修复,并且该修复已向后移植到即将发布的JDK 8u版本(8u222)中。
我有要并行处理的元素集合。当我使用时,并行性起作用。但是,当我使用时,它不会并行运行。
我有超过50种不同类型的输入,我在功能文件中的Example关键字下定义了这些输入,执行这些输入需要花费更多的时间。有没有办法并行运行这些输入?。我不想让任何人来测试这种方法。请帮忙。
问题内容: 我同时运行两个AJAX请求时遇到问题。我有一个PHP脚本正在将数据导出到XSLX。此操作需要很多时间,因此我尝试向用户显示进度。我正在使用AJAX和数据库方法。实际上,我非常确定它曾经可以工作,但是我不知道为什么,它不再在任何浏览器中都能工作。新浏览器有什么变化吗? 在数据库中正确更新进度 JS计时器正在尝试获取进度,我可以在控制台中看到它,但是所有这些请求都加载第一个脚本的整个持续时
我正在尝试动态生成阶段以并行运行,但面临下一个错误: WorkflowScript:59:第59行第5列的阶段“主”应为“步骤”、“阶段”或“平行”之一。阶段('main'){^ 这是詹金斯管道: 有办法解决这个问题吗? 谢谢
谢了。
在里面https://ci.apache.org/projects/flink/flink-docs-release-1.8/concepts/programming-model.html#parallel-数据流,有一个描述 操作符子任务的数量是该特定操作符的并行度。流的并行性始终是其生成操作符的并行性。同一程序的不同操作符可能具有不同的并行级别。 我不明白什么是流的并行性总是它的生成操作符的并