回顾CompletableFuture 异步编排

一 概述

        在 Java 8 , 新增加了一个包含 50 个方法左右的类: CompletableFuture,提供了非常强大的 Future 的扩展功能,可以帮助我们简化异步编程的复杂性,提供了函数式编程的能力,可以通过回调的方式处理计算结果,并且提供了转换和组合 CompletableFuture 的方法CompletableFuture 类实现了 Future 接口,所以你还是可以像以前一样通过`get`方法阻塞或 者轮询的方式获得结果,但是这种方式不推荐使用。 CompletableFuture 和 FutureTask 同属于 Future 接口的实现类,都可以获取线程的执行结果。

        

二 代码实践

   //自定义异步线程池,并且不存在返回值
        CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName());
        }, executor);

        //使用JDK默认的线程池,并且不存在返回值
        CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName());
        });

        //自定义异步线程池,并且存在返回值
        CompletableFuture<Integer> futureE = CompletableFuture.supplyAsync(() -> 1, executor);
        System.out.println(Thread.currentThread().getName() + "futureE.get() = " + futureE.get());

        //自定JDK默认的线程池,并且存在返回值
        CompletableFuture<Integer> futureJ = CompletableFuture.supplyAsync(() -> 1);
        System.out.println(Thread.currentThread().getName() + "futureJ.get() = " + futureJ.get());

        //whenComplete与exceptionally方法
        //whenComplete可以处理正常和异常的计算结果,另一个方法为whenCompleteAsync
        CompletableFuture<Integer> futureC = CompletableFuture.supplyAsync(() -> 10/0, executor).whenComplete((res, exception) -> {
            System.out.println("res:" + res + "exception:" + exception);
        }).exceptionally((exception)->{
            //exceptionally处理异常情况
            System.out.println("exception = " + exception);
            //发生异常的时候可以设置返回的默认值
            return 100;
        });

        System.out.println("futureC.get() = " + futureC.get());
        /**
         * whenComplete是执行当前任务的线程继续执行whenComplete的任务
         * whenCompleteAsync是whenCompleteAsync执行的内容当作一个新的任务提交给线程池。
         * 不以Async结尾的方法意味着与之前的任务使用同一个线程执行。
         * 以Async结尾的方法意味着使用其他线程执行,当使用的线程池相同的时候也可能会被同一个线程选中执行。
         **/

        //handle方法
        /**
         * whenComplete 一样,可对结果做最后的处理(可处理异常),可改变返回值。
         * 以Async和不以Async结尾任务的执行同whenComplete
         */
        CompletableFuture<Integer> futureH = CompletableFuture.supplyAsync(()->10/0,executor).handleAsync((res,exception)->{
            if (res != null) {
                res += res;
            }
            if (exception != null) {
                res = 100;
            }
            return res;
        },executor);

        System.out.println("futureH.get() = " + futureH.get());

        /**
         * thenApply 方法:当一个线程依赖另一个线程时,获取上一个任务返回的结果,并返回当前 任务的返回值。
         * thenAccept 方法:消费处理结果。接收任务的处理结果,并消费处理,无返回结果。
         * thenRun 方法:只要前面的任务执行完成,就开始执行thenRun,带有 Async 默认是异步执行的。同之前。 这些方法都要前置任务成功完成。
         * Function<? super T,? extends U> T:上一个任务返回结果的类型 U:当前任务的返回值类型
         */
        //线程串行化方法
        CompletableFuture<Integer> futureP = CompletableFuture.supplyAsync(()->10,executor).thenApplyAsync((input)-> input*input,executor);
        System.out.println("futureP = " + futureP.get());

        CompletableFuture.supplyAsync(()->10,executor).thenAcceptAsync(res->{
            System.out.println("res = " + res);
        },executor);

        CompletableFuture.supplyAsync(()->10,executor).thenRunAsync(new Thread(),executor);

        /**
         * 两个任务必须都完成,触发该任务。
         * thenCombine:组合两个 future,获取两个 future 的返回结果,并返回当前任务的返回值
         * thenAcceptBoth:组合两个 future,获取两个 future 任务的返回结果,然后处理任务,没有 返回值。
         * runAfterBoth:组合两个 future,不需要获取 future 的结果,只需两个 future 处理完任务后, 处理该任务。
         */
        //2个任务都要完成
        CompletableFuture<Integer> futureOne = CompletableFuture.supplyAsync(()->10,executor);
        CompletableFuture<String> futureTwo = CompletableFuture.supplyAsync(()->"String",executor);
        CompletableFuture<String> future = futureOne.thenCombineAsync(futureTwo, (res1, res2) -> res1 + res2, executor);
        System.out.println("future = " + future.get());

        futureTwo.thenAcceptBothAsync(futureOne,(res1,res2)->{
            System.out.println("res1:" + res1 + "res2:" +res2 );
        },executor);

        futureTwo.runAfterBothAsync(futureOne,new Thread(),executor);

        /**
         * 当两个任务中,任意一个 future 任务完成的时候,执行任务。
         * applyToEither:两个任务有一个执行完成,获取它的返回值,处理任务并有新的返回值。
         * acceptEither:两个任务有一个执行完成,获取它的返回值,处理任务,没有新的返回值。
         * runAfterEither:两个任务有一个执行完成,不需要获取 future 的结果,处理任务,也没有返 回值。
         **/
        CompletableFuture<Integer> futureThree = CompletableFuture.supplyAsync(()->100,executor);

        CompletableFuture<Integer> futureAE = futureOne.applyToEitherAsync(futureThree, (res) -> res, executor);
        System.out.println("futureAE = " + futureAE.get());

        futureOne.acceptEitherAsync(futureThree,res->{
            System.out.println("哈哈");
        },executor);

        futureThree.runAfterEitherAsync(futureOne,()->{
            System.out.println("呼呼");
        },executor);

        //get()阻塞等待所有任务完成
        CompletableFuture.allOf(future,futureAE).get();
        //任意一个任务完成即可
        Object o = CompletableFuture.anyOf(future, futureOne, futureTwo).get();
        System.out.println("o = " + o.toString());

三 结果展示

pool-1-thread-1
ForkJoinPool.commonPool-worker-1
mainfutureE.get() = 1
mainfutureJ.get() = 1
res:nullexception:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
exception = java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
futureC.get() = 100
futureH.get() = 100
futureP = 100
res = 10
future = 10String
res1:Stringres2:10
futureAE = 10
o = 10String
呼呼
哈哈

       注意

         applyToEitherAsync中的两个任务的返回值要相同,否则会出现上图提示信息。

        时间原因,暂时如此,后续再来整理,麻烦可以耐心等待。。。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值