CompletableFuture使用

CompletableFuture解决的问题

  • 解决future模式的缺点。
    a.为了解决Future虽然可以实现异步获取线程的执行结果,但是future没有提供通知机制,调用方无法得知future什么时候执行完的问题。
    b.要么使用阻塞,
    在future.get()的地方等待future返回结果,这时会变成同步操作。如果使用isDone()方法进行循环判断,就会消耗cpu资源。
  • CompletableFuture能够将回调放到与任务不同的线程中执行(其实这句话,我也不是很理解),也能将回调作为继续执行的同步函数(但是我觉的这句是关键),在于任务相同的线程中执行。他避免了传统回调的最大问题,就是能够将控制流分离到不同的事件处理器中。

CompletableFuture的静态工厂方法

  • runAsync()方法的使用,—》使用了ForkJoinPool.commonPool() 作为线程池,并进行异步执行
CompletableFuture<Void> future = CompletableFuture.runAsync(()->{
           System.out.println("hello world");
       });


       try {
           future.get();
       } catch (InterruptedException e) {
           e.printStackTrace();
       } catch (ExecutionException e) {
           e.printStackTrace();
       }

       System.out.println("completableFuture end!");

  • supplyAsync()方法的使用,—》使用了ForkJoinPool.commonPool() 作为线程池,并进行异步执行
 CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
        try {
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("completableFuture end!");

supplyAsync 和 runAsync 的区别是supplyAsyncy有返回值,而runAsync没有返回值。

  • complete的使用
        CompletableFuture<String> future = CompletableFuture.supplyAsync(()->"Hello")//        多次重复调会失效
        future.complete("World");
        future.complete("World2");
        future.complete("World3");
        future.complete("World4");
        try {
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("completableFuture end!");

如果future已经执行完毕能够返回结果,此时再调complete(T t)则会无效

运行结果:
World
completableFuture end!
  • thenApply 是将CompletableFuture 转换成CompletableFuture,也就是类型转换
  CompletableFuture<String> future = CompletableFuture
               .supplyAsync(()->"Hello")
               .thenApply(s->s+" CompletableFuture")
               .thenApply(String::toUpperCase);
       try {
           System.out.println(future.get());
       } catch (InterruptedException e) {
           e.printStackTrace();
       } catch (ExecutionException e) {
           e.printStackTrace();
       }
       System.out.println("completableFuture end!");
运行结果:
HELLO COMPLETABLEFUTURE
completableFuture end!
  • thenCompose 组合多个CompletableFuture,将前一个结果作为下一个计算的参数,他们之间存在着先后顺序。还是串行
CompletableFuture<String> future = CompletableFuture
               .supplyAsync(()->"Hello")
               .thenCompose(s->CompletableFuture.supplyAsync(()->s + " CompletableFuture"));
       //thenCompose 可以用于组合多个CompletableFuture,将前一个结果作为下一个计算的参数,它们之间存在着先后顺序
       try {
           System.out.println(future.get());
       } catch (InterruptedException e) {
           e.printStackTrace();
       } catch (ExecutionException e) {
           e.printStackTrace();
       }
运行结果:
Hello CompletableFuture

theApply 强调的是类型转换,而thenCompose强调的是执行顺序,就是前一个计算结果作为下一个计算的参数。

  • thenCombine 是将两个或多个CompletableFuture的结果进行汇总。
 CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "100");
       CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 10);
       CompletableFuture<Double> future = future1.thenCombine(future2, (s, i) -> Double.parseDouble(s + i));
       // 使用thenCombine是将future1 和future2的结果汇总,这一点跟thenCompose()不同。其中future1和future2是并行执行的。
       try {
           System.out.println(future.get());
       } catch (InterruptedException e) {
           e.printStackTrace();
       } catch (ExecutionException e) {
           e.printStackTrace();
       }
       System.out.println("completableFuture end!");
运行结果:
10010.0
completableFuture end!
  • thenAcceptBoth
    是当两个CompletableFuture都正常完成后,执行提供的action,用它来组合另一个CompletableFuture的结果。
    CompletableFuture<String> future1 = CompletableFuture.supplyAsync(()->"100");
       CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(()->70);
       CompletableFuture<Void> future = future1.thenAcceptBoth(future2,(s,i)->{
           System.out.println(s+i);
       });

运行结果:

10070
  • 当CompletableFuture完成计算结果后,我们需要对结果进行一些处理。 whenComplete 对结果的异常进行处理。
 CompletableFuture
                .supplyAsync(()->"Hello")
                .thenApply(s->s+" world")
                .thenApply(s->s+"\nThis is CompletableFuture demo")
                .thenApply(String::toLowerCase)
                .whenComplete((result,throwable)-> System.out.println(result));
  • handle 当CompletableFuture完成计算结果或者抛出异常的时候,执行提供的fn;
 // 使用lamda表达式的写法:
        CompletableFuture<Double> future = CompletableFuture
                .supplyAsync(()->"100")
                .thenApply(s->s+"10")
                .handle((s,t)->s!=null?Double.parseDouble(s):0);
        System.err.println( future.get());
  • 纯消费(执行Action)thenAccept,只会对计算结果进行消费而不会返回任何结果的方法。
   CompletableFuture.supplyAsync(()->"Hello")
               .thenApply(s->s+" world")
               .thenApply(s->s+"\nThis is CompletableFuture demo")
               .thenApply(String::toLowerCase).thenAccept((Consumer) System.out::println);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值