java并行计算效率,Java8 parallelStream 提升集合处理性能N(约等于CPU核数)倍

Stream(流)简介

Stream(流)是Java8新增对集合处理的抽象概念,类似于数据库结构化查询语句(SQL),使用Stream API 对集合数据进行操作,就类似于使用SQL执行的数据库查询。

集合可以通过stream()方法创建串行流(元素一个接一个串行处理),parallelStream()方法创建并行流(多个元素可同时进行处理)。

parallelStream集合处理效率

案例说明

代码如下:

public class StreamTest {

public static void main(String[] args) {

System.out.println("CPU核数:num=" + Runtime.getRuntime().availableProcessors() + "\n");

List list = IntStream.range(0,10).boxed().collect(Collectors.toList());

long startTime = System.currentTimeMillis();

System.out.println(list.stream().map(StreamTest::format).collect(Collectors.toList()));

System.out.println("stream() time=" + (System.currentTimeMillis() - startTime) + "\n");

startTime = System.currentTimeMillis();

System.out.println(list.parallelStream().map(StreamTest::format).collect(Collectors.toList()));

System.out.println("parallelStream() time=" + (System.currentTimeMillis() - startTime));

}

public static Integer format(Integer i) {

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName());

return i+1;

}

}

执行结果:

CPU核数:num=4

*** stream()方法数据串行执行,执行时间等于每个集合元素处理时间之和 ***

main

main

main

main

main

main

main

main

main

main

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

stream() time=1031

*** parallelStream()方法数据并行执行,执行时间约等于所有每个集合元素处理时间之后/CPU核数 ***

ForkJoinPool.commonPool-worker-1

main

ForkJoinPool.commonPool-worker-3

ForkJoinPool.commonPool-worker-2

ForkJoinPool.commonPool-worker-3

main

ForkJoinPool.commonPool-worker-1

ForkJoinPool.commonPool-worker-2

ForkJoinPool.commonPool-worker-3

main

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

parallelStream() time=312

说明:

1,parallelStream使用ForkJoinPool线程池处理任务

2,ForkJoinPool默认线程池大小为CPU核数-1(注:主线程也负责处理任务),不建议修改该大小

线程池(ForkJoinPool)

分治法

aa125b864e7b

image.png

说明:

Fork/Join框架的核心思想是采用分治法的思想。分治法:将一个复杂的问题拆分成若干个规模较小,相对独立但问题类型相同的子问题进行处理,然后再将子问题的结果合并成原始问题的完整答案。这样的问题处理策略就叫分治法。分治法三个关键步骤:1,问题拆分;2,子问题计算;3,合并。

采用分治法可以有效利用多核CPU的优势,把子问题通过并行计算,提高整体性能。

工作窃取算法

aa125b864e7b

image.png

说明:

工作窃取(work-stealing)算法是Fork/Join框架的核心理念,指当某个处理线程空闲后,为了合理利用CPU资源,就从其他线程的任务队列里面窃取任务来执行,这样能减少CPU空闲等待时间,提高空闲CPU的利用率。

注意事项

1,parallelStream()是线程不安全的

2,parallelStream()是以充分使用CPU资源来提升效率,不在多线程种使用

3,parallelStream()确保每个处理是无状态且没有关联的

总结思考

优缺点

优点

1,成倍提升集合处理效率,提高系统性能(TPS/QPS)

缺点

1,线程不安全,需要正确合理使用(解决方法:加锁、使用线程安全的集合或者采用collect()或者reduce()操作)

parallelStream适用场景

1,计算密集型集合处理(合理使用多核CPU的优势)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值