我通过创建一个简单的循环并在数组中添加元素来测试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 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;
});https://stackoverflow.com/questions/44608168
复制相似问题