温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java中CompletableFuture的使用方法是什么

发布时间:2021-12-27 16:04:32 来源:亿速云 阅读:201 作者:iii 栏目:大数据

本篇内容介绍了“java中CompletableFuture的使用方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

  java中CompletableFuture的使用

  CompletableFuture首先是一个Future,它拥有Future所有的功能,包括获取异步执行结果,取消正在执行的任务等。

  除此之外,CompletableFuture还是一个CompletionStage。

  我们看下CompletableFuture的定义:

  public class CompletableFuture implements Future, CompletionStage

  什么是CompletionStage呢?

  在异步程序中,如果将每次的异步执行都看成是一个stage的话,我们通常很难控制异步程序的执行顺序,在javascript中,我们需要在回调中执行回调。这就会形成传说中的回调地狱。

  好在在ES6中引入了promise的概念,可以将回调中的回调转写为链式调用,从而大大的提升了程序的可读性和可写性。

  同样的在java中,我们使用CompletionStage来实现异步调用的链式操作。

  CompletionStage定义了一系列的then*** 操作来实现这一功能。

  CompletableFuture作为Future使用

  调用CompletableFuture.complete方法可以立马返回结果,我们看下怎么使用这个方法来构建一个基本的Future:

  public Future calculateAsync() throws InterruptedException {CompletableFuture completableFuture= new CompletableFuture<>();Executors.newCachedThreadPool().submit(() -> {Thread.sleep(500);completableFuture.complete("Hello");return null;});return completableFuture;}

  上面我们通过调动ExecutorService来提交一个任务从而得到一个Future。如果你知道执行的结果,那么可以使用CompletableFuture的completedFuture方法来直接返回一个Future。

  public Future useCompletableFuture(){Future completableFuture =CompletableFuture.completedFuture("Hello");return completableFuture;}

  CompletableFuture还提供了一个cancel方法来立马取消任务的执行:

  public Future calculateAsyncWithCancellation() throws InterruptedException {CompletableFuture completableFuture = new CompletableFuture<>();Executors.newCachedThreadPool().submit(() -> {Thread.sleep(500);completableFuture.cancel(false);return null;});return completableFuture;}

  如果这个时候调用Future的get方法,将会报CancellationException异常。

  Future future = calculateAsyncWithCancellation();future.get(); // CancellationException

  异步执行code

  CompletableFuture提供了runAsync和supplyAsync的方法,可以以异步的方式执行代码。

  我们看一个runAsync的基本应用,接收一个Runnable参数:

  public void runAsync(){CompletableFuture runAsync= CompletableFuture.runAsync(()->{log.info("runAsync");});}

  而supplyAsync接受一个Supplier:

  public void supplyAsync(){CompletableFuture supplyAsync=CompletableFuture.supplyAsync(()->{return "supplyAsync";});}

  他们两个的区别是一个没有返回值,一个有返回值。

  组合Futures

  上面讲到CompletableFuture的一个重大作用就是将回调改为链式调用,从而将Futures组合起来。

  而链式调用的返回值还是CompletableFuture,我们看一个thenCompose的例子:

  CompletableFuture completableFuture

  = CompletableFuture.supplyAsync(() -> "Hello").thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " World"));

  thenCompose将前一个Future的返回结果作为后一个操作的输入。

  如果我们想合并两个CompletableFuture的结果,则可以使用thenCombine:

  public void thenCombine(){CompletableFuture completableFuture= CompletableFuture.supplyAsync(() -> "Hello").thenCombine(CompletableFuture.supplyAsync(() -> " World"), (s1, s2) -> s1 + s2));}

  如果你不想返回结果,则可以使用thenAcceptBoth:

  public void thenAcceptBoth(){CompletableFuture future = CompletableFuture.supplyAsync(() -> "Hello").thenAcceptBoth(CompletableFuture.supplyAsync(() -> " World"),(s1, s2) -> System.out.println(s1 + s2));}

  thenApply() 和 thenCompose()的区别

  thenApply()和thenCompose()两个方法都可以将CompletableFuture连接起来,但是两个有点不一样。

  thenApply()接收的是前一个调用返回的结果,然后对该结果进行处理。

  thenCompose()接收的是前一个调用的stage,返回flat之后的的CompletableFuture。

  简单点比较,两者就像是map和flatMap的区别。

  并行执行任务

  当我们需要并行执行任务时,通常我们需要等待所有的任务都执行完毕再去处理其他的任务,那么我们可以用到CompletableFuture.allOf方法:

  public void allOf(){CompletableFuture future1= CompletableFuture.supplyAsync(() -> "Hello");CompletableFuture future2= CompletableFuture.supplyAsync(() -> "Beautiful");CompletableFuture future3= CompletableFuture.supplyAsync(() -> "World");CompletableFuture combinedFuture= CompletableFuture.allOf(future1, future2, future3);}

  allOf只保证task全都执行,而并没有返回值,如果希望带有返回值,我们可以使用join:

  public void join(){CompletableFuture future1= CompletableFuture.supplyAsync(() -> "Hello");CompletableFuture future2= CompletableFuture.supplyAsync(() -> "Beautiful");CompletableFuture future3= CompletableFuture.supplyAsync(() -> "World");String combined = Stream.of(future1, future2, future3).map(CompletableFuture::join).collect(Collectors.joining(" "));}

  上面的程序将会返回:“Hello Beautiful World”。

  异常处理

  如果在链式调用的时候抛出异常,则可以在最后使用handle来接收:

  北海房价走势 http://house.bh.goufang.com/lpfangjia/

  public void handleError(){String name = null;CompletableFuture completableFuture= CompletableFuture.supplyAsync(() -> {if (name == null) {throw new RuntimeException("Computation error!");}return "Hello, " + name;}).handle((s, t) -> s != null ? s : "Hello, Stranger!");}

  这和Promise中的catch方法使用类似。

“java中CompletableFuture的使用方法是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI