day123-商城业务-异步编排-CompletableFuture

1.为什么要使用这玩意

如下,现在我们这样一个场景,我们根据自己的需要查出了相关商品,然后点击某商品进去查看此商品详情

那么,我们需要如下6步进行查询,如果单纯按顺序一步步执行,那么执行时间是他们每步执行时间之和,那么此时就需要对他们进行分析,

我们点击商品时,此时我们有sku的id,很明显,前三步彼此之间没有什么影响,这时候我们可以用三个线程同时执行,而4,5,6步,又需要通过第一步

获取到他的所属spu的信息,所以是需要第一步先执行完的,那么此时我们合理的设计代码的执行逻辑就是开三个线程执行1,2,3步,等到他们最长的

那个任务执行完时,开三个线程执行4,5,6步,此时4,5,6依赖于前面1 执行的结果,像这种场景是很常见的业务场景,常用的东西到了我们这年代基本

都有了封装好的框架,此时我们就来到 CompletableFuture,他就是用来做异步编排的.

2.启动异步任务

有两种方式,一种没返回值,一种有返回值  返回值通过 get方法获取

实例如下

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
            int n = 10 / 2;
            System.out.println("我没返回值,Thread-" + Thread.currentThread() + "中输出:" + n);
        });

        Thread.sleep(100);

        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
            int n = 10 / 2;
            System.out.println("我有返回值,Thread-" + Thread.currentThread() + "中输出:" + n);
            return n;
        });
        System.out.println("我的返回值是:"+integerCompletableFuture.get());

    }

控制台打印结果如下:

3.完成回调与异常的感知

示例如下, whenComplete是在调用者前面任务执行完后继续执行内容,可以获取前面任务的返回结果与捕获的异常,当然异常了返回结果一般都是null,exceptionally是捕获异常并且回调方法,来返回新的结果

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
            int n = 10 / 0;
            System.out.println("我有返回值,Thread-" + Thread.currentThread() + "中输出:" + n);
            return n;
        }).whenCompleteAsync((res,exception)->{
            System.out.println("res:"+res+" exception:"+exception.getMessage());
        }).exceptionally((throwable)->{
            return 0;
        });
        System.out.println("返回结果:"+integerCompletableFuture.get());
    }

 

4.handle最终处理

有异常时:

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
            int n = 10 / 0;
            System.out.println("我有返回值,Thread-" + Thread.currentThread() + "中输出:" + n);
            return n;
        }).handle((res,exception) ->{
            if(res != null){
                res = res*2;
            }
            if(exception != null){
                res = 0;
            }
            return res;
        });
        System.out.println("返回结果:"+integerCompletableFuture.get());
    }

没异常时:

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
            int n = 10 / 2;
            System.out.println("我有返回值,Thread-" + Thread.currentThread() + "中输出:" + n);
            return n;
        }).handle((res,exception) ->{
            if(res != null){
                res = res*2;
            }
            if(exception != null){
                res = 0;
            }
            return res;
        });
        System.out.println("返回结果:"+integerCompletableFuture.get());
    }

5.线程串行化

示例没啥好写的了

6.两任务组合,都要完成

任务1,任务2都执行完后执行 的方法 

示例如下,这里演示的是第一种,获取前俩任务的返回值,并且执行相关操作后返回新的值,后两种就不演示了

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        CompletableFuture<Object> integerCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一执行中...");
            int n = 10 / 2;
            System.out.println("任务一执行结束");
            return n;
        });

        CompletableFuture<Object> integerCompletableFuture2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务二执行中...");
            int n = 5 / 2;
            System.out.println("任务二执行结束.");
            return n;
        });

        CompletableFuture<String> objectCompletableFuture = integerCompletableFuture1.thenCombine(integerCompletableFuture2, (r1, r2) -> {
            String r3 = "";
            System.out.println("任务三执行中");
            r3 += r3+r1+","+r2;
            System.out.println("任务三执行结束");
            return r3;
        });

        System.out.println("任务三返回结果:"+objectCompletableFuture.get());
    }

7.两任务组合,一个完成

跟上面几个方法的使用方法一样,区别就是这里是两个任务任意一个完成即可,然后执行时参数中只接收一个返回值

8.  多任务组合

get方法是阻塞式等待,一定要执行,不然无法保证所有任务全部完成才执行后面的代码

示例如下

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        CompletableFuture<Object> integerCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一查询商品图片执行中...");
            System.out.println("任务一执行结束");
            return "huawei121.jpg";
        });

        CompletableFuture<Object> integerCompletableFuture2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务二查询商品属性执行中...");
            System.out.println("任务二执行结束.");
            return "256G+黑色";
        });

        CompletableFuture<Object> integerCompletableFuture3 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务二查询商品品牌执行中...");
            System.out.println("任务二执行结束.");
            return "华为";
        });

        CompletableFuture<Void> completableFuture = CompletableFuture.allOf(integerCompletableFuture1, integerCompletableFuture2, integerCompletableFuture3);
        //此方法会阻塞式等待,直到三个方法都执行完
        completableFuture.get();
        System.out.println("main线程结束...");
    }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我才是真的封不觉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值