java8 forkjoinpool_ForkJoinPool性能Java 8 vs 11

考虑以下代码:

package com.sarvagya;

import java.util.Arrays;

import java.util.List;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.ForkJoinPool;

import java.util.stream.Collectors;

public class Streamer {

private static final int LOOP_COUNT = 2000;

public static void main(String[] args){

try{

for(int i = 0; i < LOOP_COUNT; ++i){

poolRunner();

System.out.println("done loop " + i);

try{

Thread.sleep(50L);

}

catch (Exception e){

System.out.println(e);

}

}

}

catch (ExecutionException | InterruptedException e){

System.out.println(e);

}

// Add a delay outside the loop to make sure all daemon threads are cleared before main exits.

try{

Thread.sleep(10 * 60 * 1000L);

}

catch (Exception e){

System.out.println(e);

}

}

/**

* poolRunner method.

* Assume I don't have any control over this method e.g. done by some library.

* @throws InterruptedException

* @throws ExecutionException

*/

private static void poolRunner() throws InterruptedException, ExecutionException {

ForkJoinPool pool = new ForkJoinPool();

pool.submit(() ->{

List numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10, 11,12,14,15,16);

List collect = numbers.stream()

.parallel()

.filter(xx -> xx > 5)

.collect(Collectors.toList());

System.out.println(collect);

}).get();

}

}

在上面的代码中,poolRunner方法正在创建一个ForkJoinPool并向其提交一些任务.当使用Java 8并将LOOP_COUNT保持为2000时,我们可以看到创建的最大线程大约为3600,如下所示

l3Jho.png

图:分析

jpomr.png

图:线程信息.

经过一段时间后,所有这些线程都会下降到接近10.但是,在OpenJDK 11中保持相同的LOOP_COUNT会产生以下错误:

[28.822s][warning][os,thread] Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 1024k, guardsize: 4k, detached.

[28.822s][warning][os,thread] Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 1024k, guardsize: 4k, detached.

[28.822s][warning][os,thread] Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 1024k, guardsize: 4k, detached.

Exception in thread "ForkJoinPool-509-worker-5" java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached

at java.base/java.lang.Thread.start0(Native Method)

at java.base/java.lang.Thread.start(Thread.java:803)

at java.base/java.util.concurrent.ForkJoinPool.createWorker(ForkJoinPool.java:1329)

at java.base/java.util.concurrent.ForkJoinPool.tryAddWorker(ForkJoinPool.java:1352)

at java.base/java.util.concurrent.ForkJoinPool.signalWork(ForkJoinPool.java:1476)

at java.base/java.util.concurrent.ForkJoinPool.deregisterWorker(ForkJoinPool.java:1458)

at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:187)

它很快达到最大线程限制.将LOOP_COUNT保持为500,工作正常,但是,这些线程非常缓慢地清除并达到大约500个线程的平台.见下图:

gvUU9.png

图:OpenJDK 11中的线程信息

dNB1r.png

图:OpenJDK中的分析11

线程在JDK 8中是PARKED,但在JDK 11中是WAIT.在Java 11中也应该减少守护程序线程的数量,但是它很慢并且不能按预期工作.而且,假设我无法控制poolRunner方法.考虑这种方法是由一些外部库提供的.

这是OpenJDK 11的问题,还是我在代码中做错了什么.谢谢.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值