在java8并行流中自定义线程池

1.概览

java8引入了流的概念,流是作为一种对数据执行大量操作的有效方式。并行流可以被包含于支持并发的环境中。这些流可以提高执行性能-以牺牲多线程的开销为代价

在这篇短文中,我们将看一下 Stream API的最大限制,同时看一下如何让并行流和线程池实例(ThreadPool instance)一起工作。


2.并行流Parallel Stream

我们先以一个简单的例子来开始-在任一个Collection类型上调用parallelStream方法-它将返回一个可能的并行流。

@Test

publicvoidgivenList_whenCallingParallelStream_shouldBeParallelStream(){

    List aList = newArrayList<>();

    Stream parallelStream = aList.parallelStream();

    assertTrue(parallelStream.isParallel());

}

这样的流的默认处理流程是使用ForkJoinPool.commonPool(),这是一个被整个应用程序所共享的线程池。


3.自定义线程池

在处理流的时候,我们可以传递自定义一个线程池。下面的例子中,我们有一个并行流,这个并行流使用了一个自定义的线程池去计算1到 1,000,000的和:

@Testpublic void giveRangeOfLongs_whenSummedInParallel_shouldBeEqualToExpectedTotal() throws InterruptedException, ExecutionException { long firstNum = 1; long lastNum = 1_000_000; List aList = LongStream.rangeClosed(firstNum, lastNum).boxed()

      .collect(Collectors.toList());

    ForkJoinPool customThreadPool = new ForkJoinPool(4);

    long actualTotal = customThreadPool.submit(

      () -> aList.parallelStream().reduce(0L, Long::sum)).get();


    assertEquals((lastNum + firstNum) * lastNum / 2, actualTotal);

}

我们使用ForkJoinPool的构造方法并设定并行级别为4去创建一个线程池。要想确定不同环境的最优值(optimal),我们需要试验一下。一个好的做法就是,基于你CPU的核数来确定并行级别的数值。


4.总结

我们简要地看了一下,如何使用一个自定义的Thread Pool运行并行流。只要在正确的环境中配置了合适的平行级别,就能在确定的情况下获得较高的执行性能。

本文中引用的完整代码都可在github上找到:ON Github

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Java8 in action 没有共享的可变数据,将方法和函数即代码传递给其他方法的能力就是我们平常所说的函数式...
    铁牛很铁阅读 1,410评论 1 2
  • 通过上一篇(JUC源码分析-线程池篇(四):ForkJoinPool - 1)的讲解,相信同学们对 ForkJoi...
    泰迪的bagwell阅读 7,959评论 16 18
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 137,128评论 19 139
  •   一个任务通常就是一个程序,每个运行中的程序就是一个进程。当一个程序运行时,内部可能包含了多个顺序执行流,每个顺...
    OmaiMoon阅读 1,831评论 0 12
  • 一、Thrift的安装(MAC) 1、安装Homebrew 注意 关于最新版mac(OSX High Sierra...
    binbin1018阅读 507评论 0 0

友情链接更多精彩内容