我通过创建一个简单的循环并在数组中添加元素来测试java 8并行流api的性能。
我得到了一个巨大的性能比非平行的一个。
但是当我检查我的任务管理器时,我看到一个不受控制的CPU使用情况,在这段时间内它消耗了我所有的CPU。

这是我的代码样本
public static void withIfElse(boolean sorted) {
int[] arr = new int[32768];
Random rand = new Random();
for(int i = 0;i < arr.length;i++)
arr[i] = rand.nextInt(256);
if(sorted)
Arrays.parallelSort(arr);
long nst = System.currentTimeMillis();
long sum = 0;
for(int j=0;j<100000;j++) {
sum += Arrays.stream(arr).parallel().filter(m->m>=128).reduce((m,n)-> m+n).getAsInt();
}
System.out.printf("Time taken for boolean %b is %d ms. \n",sorted,(System.currentTimeMillis()-nst));
}我能够实现近2倍至8倍的性能提升。
但是,
Cpu的使用是无法控制的。有没有办法将java强制到只有两个核心?
我也试过
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism","1");
但是CPU的使用率仍然很高。
还建议使用并行流吗?因为假设在我的应用程序中我有10个用户线程,或者一个web应用程序,其中每个请求都是一个线程,在这种情况下,如果我在多个线程上启动了一个并行流,最终占用了我所有的cpu,那么就会有太多的上下文切换。
发布于 2017-06-17 21:17:10
我的0.02美元:huge performance boost over non parallel one。大块头可能有点太大了。这可能有很好的理由-首先,你测试的方式。这是如此关键的是,有一个问题已经超过500票,特别是这个:微基准。您可能认为编写了很好的测试,但是jvm可能有不同的计划。
对于中度数据,序列流可能比并行流更快。这是一个更多的工作,必须由并行流完成。但是如果没有实际的测量,这几乎是不可能说出来的;但是这里有来自这个领域最好的建议,比如这。
当您说您希望将java限制在某些核心时,简单的回答是,您不能;从java代码,也就是。它必须从OS做,如果它是可行的。您通过java.util.concurrent.ForkJoinPool.common.parallelism启用的是限制线程,而不是内核。
一个线程可以被拆分到多个cpus上--它取决于操作系统本身。
发布于 2017-06-17 18:51:28
默认情况下,并行流在系统范围的ForkJoinPool中运行,为您的计算机上可用的每个核心提供一个线程。
如果您想改变这种行为,可以在您选择的ForkJoinPool中运行并行流:
ForkJoinPool fjp = new ForkJoinPool(2);
ForkJoinTask<Long> sumFuture = fjp.submit(() -> {
long sum = 0;
for(int j=0;j<100000;j++) {
sum += Arrays.stream(arr).parallel().filter(m->m>=128).reduce((m,n)-> m+n).getAsInt();
}
return sum;
});发布于 2022-05-13 04:48:50
我遇到了一个类似的问题,我的代码使用并行流()。并行流的问题在于它使用了所有的CPU核心。我有一个由48个核心组成的系统下面是CPU利用率的屏幕截图。

为了使并行流使用更少的CPU,我在使用CLI中的以下命令提交jar时,更改了ForkJoinCommonPool中的并行数。
java -Djava.util.concurrent.ForkJoinPool.common.parallelism=20 -jar <jar-name>
在此之后,我的CPU利用率图片如下所示

https://stackoverflow.com/questions/44608168
复制相似问题