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();
    }
上一篇:航空巨头公司也来搞“飞行汽车”,以后我们可以直接“滴滴”叫飞机了


下一篇:DevExpress学习03——label控件的背景色问题