java并发编程学习16--CompletableFuture(三)

发布时间:2019-11-17 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了java并发编程学习16--CompletableFuture(三)脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

【最佳价格查询器的优化

由于我们的两个远程服务:1.查询价格,2.查询折扣价格都是基于网络的。所以很容易出现某一个商店的数据迟迟无法返回的情况。由于这些原因,我希望查询器在查询时能够将拿到数据先返回过来,而不是等待所有的异步查询完成后集中返回一个List。
我们首要需要避免的就是:等待创建一个包含所有价格的List。我们应该直接处理CompletableFuture流,然后去响应他的completion事件,每一个CompletableFuture对象完成时获取到相应的返回值。

先将Discount的折扣服务延迟时间修改为随机值:

    //计算折扣价格     PRivate static Double @H_777_25@apply(double price ,Code code){         //模拟远程操作的延迟         delay();         return (price * (100 - code.PErcantage)) / 100;     }     private static void delay(){         try {             //随机延迟时间             int delay = 500 + random.nextInt(2000);             Thread.sleep(delay);         } catch (InterruptedException e) {             e.printStackTrace();         }     }

开始实现最佳价格查询器:

package BestPriceFinder;  import java.util.Arrays; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.stream.Collectors; import java.util.stream.Stream;  /**  * 最佳价格查询器  */ public class BestFinder {      List<Shop> shops = Arrays.asList(             new Shop("A"),             new Shop("B"),             new Shop("C"),             new Shop("D"),             new Shop("E"),             new Shop("F"),             new Shop("G"),             new Shop("H"),             new Shop("I"),             new Shop("J")     );      public void findPricesContinue(String product){         long st = System.currentTimeMillis();         Stream<CompletableFuture<String>> futurePrices = shops.stream()                 //首先异步获取价格                 .map(shop -> CompletableFuture.supplyAsync(() -> shop.getPriceFormat(product),myExecutor))                 //将获取的字符串解析成对象                 .map(future -> future.thenApply(Quote::parse))                 //使用另一个异步任务有获取折扣价格                 .map(future -> future.thenCompose(quote -> CompletableFuture.supplyAsync(() -> Discount.applyDiscount(quote),myExecutor)));         //thenAccept()会在CompletableFuture完成之后使用他的返回值,这里会持续执行子线程         CompletableFuture[] futures = futurePrices.map(f -> f.thenAccept(s -> {                                                                             String sout = String.format("%s done in %s mesc",s,(System.currentTimeMillis() - st));                                                                             System.out.println(sout);                                                                          }))                                                   .toArray(size -> new CompletableFuture[size]);         //allOf()工厂方法接受由CompletableFuture对象构成的数组,这里使用其等待所有的子线程执行完毕         CompletableFuture.allOf(futures).join();     }          /**      * 异步查询      * 相比并行流的话CompletableFuture更有优势:可以对执行器配置,设置线程池大小      */     @SuppressWarnings("all")     private final Executor myExecutor = Executors.newFixedThreadPool(Math.min(shops.size(), 100), new ThreadFactory() {         @Override         public Thread newThread(Runnable r) {             Thread t = new Thread(r);             //使用守护线程保证不会阻止程序的关停             t.setDaemon(true);             return t;         }     });    

java并发编程学习16--CompletableFuture(三)

thenAccept():提供了在CompletableFuture对象完成后使用他的返回值的功能。这样我们的每一个CompletableFuture完成后就会打印他的返回值,最终等待所有的子线程完毕。

allOf():工厂方法接受由CompletableFuture对象构成的数组,数组中所有的CompletableFuture完成后它返回一个CompletableFuture<Void>对象。

anyOf():厂方法接受由CompletableFuture对象构成的数组,返回数组中第一个完成的CompletableFuture的返回值CompletableFuture<Object>对象。

@H_126_214@【小结
  1. 执行耗时的操作,尤其是依赖了远程服务的操作,应该使用异步任务提高效率。
  2. 尽可能的提供异步API,使用CompletableFuture类提供的特性可以轻松实现。
  3. CompletableFuture类提供了异常机制,可以管理与抛出异步任务中执行的异常。
  4. 同步的API封装到CompletableFuture中可以以异步方式使用其结果。
  5. 异步的API可以通过CompletableFuture进行合并,无论他们之间是否有依赖关系。
  6. 可以为CompletableFuture注册一个回调函数,在执行完毕时使用。
  7. 可以决定什么时候结束运行,是所有的CompletableFuture结束后,还是第一个CompletableFuture结束时就完成。

脚本宝典总结

以上是脚本宝典为你收集整理的java并发编程学习16--CompletableFuture(三)全部内容,希望文章能够帮你解决java并发编程学习16--CompletableFuture(三)所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。