自定义java 8 并行流的线程池

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/neweastsun/article/details/85932025

自定义java 8 并行流的线程池

java 8 引入Stream的概念,一种有效的批量数据处理方式。在支持并发环境中可以获得并行stream。并行流能提升性能——采用多行程方式执行。本文我们看看Stream API 的最大限制,以及如何给并行流增加自定义线程池。

并行流

先从一个简单示例开始,调用Collection类型的parallelStream 方法——创建并行流:

@Test
public void givenList_whenCallingParallelStream_shouldBeParallelStream(){
    List<Long> aList = new ArrayList<>();
    Stream<Long> parallelStream = aList.parallelStream();
         
    assertTrue(parallelStream.isParallel());
}

并发流缺省使用ForkJoinPool.commonPool()方法,整个应用共享一个线程池。

自定义线程池

在处理并发流时,我们可以传递自定义的线程池。下面示例中使用自定义线程池的并发流计算1到1,000,000之和:

@Test
public void giveRangeOfLongs_whenSummedInParallel_shouldBeEqualToExpectedTotal() 
  throws InterruptedException, ExecutionException {
     
    long firstNum = 1;
    long lastNum = 1_000_000;
 
    List<Long> 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个线程池。为了确定不同环境的最优值,需要进行一些实验,但是一个好的经验法则是根据CPU的核数来选择最优值。接下来,调用reduce方法并行计算数据之和。

这个简单示例不可能展示自定义线程池的完整用法,但不使用公共线程池运行费时任务或应用中其他任务的好处是显而易见的。

总结

我们简要说明了如何使用自定义线程池运行并行流任务。在适当的环境中正确地使用并行机制,可以在某中程度上获得性能提升。

猜你喜欢

转载自blog.csdn.net/neweastsun/article/details/85932025