java8学习:CompletableFuture方法使用-阿里云开发者社区

开发者社区> 期待l> 正文

java8学习:CompletableFuture方法使用

简介:
+关注继续查看
  • 下面是自己总结的一部分的api的使用,当然下面有些方法后面加上Async就会变为异步的

    /**
     * 变换:参数为Function接口
     * thenApply:将上一个结果当做这次thenApply的参数传入,加以处理后,返回一个值
     * 可以传入T返回T也可以传入T返回U
     */
    public void thenApply() {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> 1).thenApply(i -> String.valueOf(i));
        String i = future.join();
        System.out.println(i); //1
    }
    
    /**
     * 消费
     * 参数为Consumer接口
     * thenAccept:将上一个的结果当做这次的参数传入,但是无返回值
     */
    public void thenAccept() {
        CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> 1).thenAccept((integer -> System.out.println(integer)));
        future.join();  //1
    }
    
    public void thenCompose() {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 1) //提供第一个CompletableFuture结果值
                .thenCompose((i) ->    //将上一个结果值传入下一个CompletableFuture
                        CompletableFuture.supplyAsync(() -> i + 2));  //对传入的结果值进行处理
        Integer join = future.join();
        System.out.println(join);
    }
    
    /**
     * 结合两个结果得到一个最终值
     * 逻辑处理需要的是BiFunction接口
     * 需要两个CompletableFuture结果,并且需要有处理两个结果的逻辑
     * 两个CompletableFuture返回的结果不需要一致
     */
    public void thenCombine() {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello ")   //第一个CompletableFuture返回结果
                .thenCombine(CompletableFuture.supplyAsync(() -> 1),          //第二个CompletableFuture返回结果
                        (future1, future2) -> future1 + future2);      //处理两个结果的逻辑
        String join = future.join();
        System.out.println(join); //Hello World
    }
    
    /**
     * 跟上面的差不多,只不过这里处理逻辑需要的是一个BiConsumer接口,无返回值而已
     */
    public void thenAcceptBoth() {
        CompletableFuture<Void> both = CompletableFuture.supplyAsync(() -> "Hello ")   //第一个CompletableFuture返回结果
                .thenAcceptBoth(CompletableFuture.supplyAsync(() -> "World"), //第二个CompletableFuture返回结果
                        (future1, future2) -> System.out.println(future1 + future2));//处理两个结果的逻辑
        both.join(); //Hello World
    }
    
    /**
     * 两个CompletableFuture一起执行,哪个先执行完就用哪个CompletableFuture的结果
     * 处理逻辑需要的参数是一个Function接口
     * 下面整体代码的逻辑是返回1的睡眠一秒,返回2的睡眠0.3秒,所以返回2的肯定比1要快,所以结果为2,然后应用到处理逻辑上
     * 最终结果就是为 2 done
     * 两个CompletableFuture返回的参数需要一致
     * 这适用于两种渠道完成同一个事情,就可以调用这个方法,找一个最快的结果进行处理,最终有返回值。
     */
    public void applyToEither() {
        CompletableFuture<String> apply = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "1";
        }).applyToEither(
                CompletableFuture.supplyAsync(() -> {
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return "2";
                }),
                (future) -> future + " done"      //对于首先完成的CompletableFuture任务之后执行的逻辑
        );
        String join = apply.join();
        System.out.println(join);//2 done
    }
    
    /**
     * 与上面使用方法一致,只是多加了一个选项
     * 结果为3 three
     */
    public void applyToEithers() {
        CompletableFuture<String> apply = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "1";
        }).applyToEither(
                CompletableFuture.supplyAsync(() -> {
                    try {
                        Thread.sleep(800);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return "2";
                }),(future) -> future + " done"      //对于首先完成的CompletableFuture任务之后执行的逻辑
        ).applyToEither(
                CompletableFuture.supplyAsync(() -> {
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return "3";
                }),(future -> future + " three")
        );
        String join = apply.join();
        System.out.println(join);//2 done
    }
    
    /**
     * 对于出错的处理过程进行补偿,即如果future出错,会运行exceptionally里的Function函数
     * 当然没有错就不会运行后面指定的函数
     */
    @Test
    public void exceptionally() {
        CompletableFuture<String> exceptionally = CompletableFuture.supplyAsync(() -> {
            int i = 1 / 0 ;
            return "1";
        }).exceptionally(ex -> {
            ex.printStackTrace();
            return "error";
        });
        String join = exceptionally.join();
        System.out.println(join);
    }
    
    /**
     * 输出
     * error
     * java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
     *     at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
     *     at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
     *     at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1592)
     *     at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582)
     *     at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
     *     at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
     *     at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
     *     at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
     * Caused by: java.lang.ArithmeticException: / by zero
     *     at com.qidai.demotest.MyTestx.lambda$exceptionally$18(MyTestx.java:125)
     *     at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590)
     *     ... 5 more
     */
    
    /**
     * 与上面的thenAccept相比较,这个方法并不需要输入参数,相同点是都是无返回值
     */
    public void thenRun() {
        CompletableFuture<Void> runnable = CompletableFuture.supplyAsync(() -> "1").thenRun(() -> System.out.println("runnable"));
        runnable.join();
    }

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
java8学习:通过行为参数化传递代码
内容来自《 java8实战 》,本篇文章内容均为非盈利,旨为方便自己查询、总结备份、开源分享。如有侵权请告知,马上删除。书籍购买地址:[java8实战] 如下一段代码请看 @Test public void test() throws Exception { List li.
2994 0
【Java】java使用反射访问对象方法和成员变量
虽然java是一门静态语言,但是java的反射机制却给java提供了很强大的动态特性,其特点是能让java支持在运行时才能得知名称与内部结构的类,并能访问其所有的方法和成员变量,包括私有方法和私有成员变量。下面我写了一个比较简洁的测试代码,供参考和使用。 测试类 //OBClass.java package com.obo.javaassistdemo; public class
1484 0
使用RDP时发生AtBroker.exe error的解决方法
试想,如果你在家里使用RDP连接自己办公室里的电脑,但是却发生Atboker.exe error,使你无法继续工作,是不是很郁闷?       今天晚上,和往常一样回到宿舍,打开电脑【XP】=》运行=》mstsc=》使用RDP连接实验室中的电脑【Vista】时,远程电脑的桌面上再次出现Atbroker.exe error,点击确定之后,惨了,只能看到黑色的桌面,什么都没有,关闭mstsc,并再次打开,依然发生同样的错误。
997 0
基于多任务学习和负反馈的深度召回模型
召回结果的好坏对整个推荐结果有着至关重要的影响,最近的一系列实践和研究表明,基于行为序列的深度学习推荐模型搭配高性能的近似检索算法可以实现既准又快的召回性能;与此同时,用户在天猫精灵上还可以进行实时指令操控(歌名点播:“播放七里香”、风格流派推荐点播:“来点摇滚”、主动切歌:“下一首”等),如何利用这些丰富的反馈信息改进召回模型的性能,他们是怎么做的呢?
1193 0
+关注
期待l
世界的模样,在于你看它的角度...
64
文章
3
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载