Bootstrap

对比stream、parallelStream、CompletableFuture执行效率

🍰 个人主页:_小白不加班__
🍞文章有不合理的地方请各位大佬指正。
🍉文章不定期持续更新,如果我的文章对你有帮助➡️ 关注🙏🏻 点赞👍 收藏⭐️

若不了解streamCompletableFuture基本使用,可移步往期文章

  1. 🔥《理解stream的使用,从匿名内部类到stream》学习Stream的基本使用
  2. 🔥🔥《CompletableFuture异步编程》学习了CompletableFuture基本使用

一、parallelStream是什么

简单来说—基于 Java Stream API 的一个并行处理流

   //前n个自然数求和
   static Long parallelSum(long n) {
       return Stream.iterate(1L, i -> i + 1)
               .limit(n)
               .parallel()
               .reduce(0L, (x, y) -> x + y);
   }
   @Test
   void test() {
       //1-100累计求和5050
       log.info("1-100累计求和{}", parallelSum(100));
   }

在这里插入图片描述

  • 并行流内部使用了默认的ForkJoinPool, 它默认的 线程数量就是你的处理器数量
  • 可通过java代码执行Runtime.getRuntime().availableProcessors();查看本电脑处理器个数

二、stream、parallelStream、CompletableFuture执行效率执行效率

场景:商品集合如下,取出商品集合所有商品的价格,

//商品类
@Data
 @AllArgsConstructor
 public static class Shop {
     private String name;
     private Integer price;

     //睡眠1秒 模拟操作过程
     private Integer getPrice() {
         try {
             Thread.sleep(1000L);
         } catch (InterruptedException e) {
             throw new RuntimeException(e);
         }
         return price;
     }
 }

 private final List<Shop> shops = Arrays.asList(
         new Shop("BestPrice", 1),
         new Shop("LetsSaveBig", 2),
         new Shop("MyFavoriteShop", 3),
         new Shop("BuyItAll", 4));
1.stream

集合中的元素顺序执行

@Test
 public void test() {
     long start = System.nanoTime();
     handleMap();
     long time = (System.nanoTime() - start) / 1_000_000;
     log.info("执行时长:【{}】ms", time);//4044ms
 }

 public List<Integer> handleMap() {
     return shops.stream()
             .map(shop -> shop.getPrice())
             .collect(Collectors.toList());
 }
2.parallelStream
 @Test
 public void test() {
     long start = System.nanoTime();
     handleMap();
     long time = (System.nanoTime() - start) / 1_000_000;
     log.info("执行时长:【{}】ms", time);//1013ms
 }

 public List<Integer> handleMap() {
     return shops.parallelStream()
             .map(shop -> shop.getPrice())
             .collect(Collectors.toList());
 }
  • 根据前文所说parallelStream最大并行数为处理器个数,当前环境8个处理器
  • 当集合中有9个元素时,任务数大于我当前最大处理器数量,执行时间大约 2018ms
3.CompletableFuture

异步非阻塞执行,默认使用公共线程池ForkJoinPool,线程池数量也等于处理器个数

@Test
 public void test1() {
     long start = System.nanoTime();
     handleMap();
     long time = (System.nanoTime() - start) / 1_000_000;
     log.info("执行时长:【{}】ms", time);//1014ms
 }

 public List<Integer> handlMap() {
     List<CompletableFuture<Integer>> collect = shops.stream()
             .map(shop -> CompletableFuture.supplyAsync(() -> shop.getPrice()))
             .collect(Collectors.toList());
     return collect.stream()
             .map(CompletableFuture::join)
             .collect(Collectors.toList());
 }
4.如何选择CompletableFuture、parallelStream
  1. 如果是计算密集型操作,没有I/O,推荐使用parallelStream,实现简单效率也高
  2. 操作流程复杂,涉及等待I/O操作,使用CompletableFuture灵活性更好。CompletableFuture可以实现线程之间顺序依赖、结果依赖

参考:《java8 实战》

🍉文章不定期持续更新,如果我的文章对你有帮助➡️ 关注🙏🏻 点赞👍 收藏⭐️

;