并行流使用注意事项

一、FolkJoinPool

JDK 7引入了新的线程池FolkJoinPool,它使用了一个无限队列来保存需要执行的任务,而线程的数量则是通过构造函数传入,如果没有向构造函数中传入希望的线程数量,那么当前计算机可用的CPU数量会被设置为线程数量作为默认值。

//获取CPU核心
Runtime.getRuntime().availableProcessors();

这个线程的工作核心主要是两个:一个是分治思想,一个是工作窃取

分治思想
每个任务都只fork出两个子任务,如果负责fork子任务的当前任务不做任何事情,那么最终将只有叶子节点真正做事情,其它节点都只是负责fork子任务与合并结果
在这里插入图片描述
  |

工作窃取:一个大的任务切分出的子任务会提交到线程池的任务队列中,4个线程从任务队列中获取任务执行,哪个线程执行的任务快,哪个线程执行的任务就多,只有队列中没有任务线程才是空闲的,这就是工作窃取。

适合场景:使用ForkJoinPool能够使用数量有限的线程来完成非常多的具有父子关系的任务

注意问题 :ForkJoinPool在执行过程中,会创建大量的子任务,堆内存和垃圾回收不友好


二、并行流Parallel Stream

并行流也是使用的ForkJoinPool的,但默认线程数量只能是CPU的核心数量,可以通过以下方式更改。

//修改并行流使用的ForkJoinPool的线程数量为12
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism","12");

但是,笔者不建议这样,因为并行流使用的FolkJoinPool是整个JVM进程全局唯一的线程池,如果改了,虽然对你当前的业务逻辑来说,算是调优了,但对于项目中其它地方只是用来做非耗时的并行流运算,性能就差了。

我们可以验证是否并行流使用的FolkJoinPool是全局唯一的线程池。

List<Integer> list = new ArrayList<>(100);
for (int i = 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值