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();
    }
目录
相关文章
|
2月前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
2月前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
84 9
|
2月前
|
安全 Java 开发者
Java中WAIT和NOTIFY方法必须在同步块中调用的原因
在Java多线程编程中,`wait()`和`notify()`方法是实现线程间协作的关键。这两个方法必须在同步块或同步方法中调用,这一要求背后有着深刻的原因。本文将深入探讨为什么`wait()`和`notify()`方法必须在同步块中调用,以及这一机制如何确保线程安全和避免死锁。
47 4
|
2月前
|
Java
深入探讨Java中的中断机制:INTERRUPTED和ISINTERRUPTED方法详解
在Java多线程编程中,中断机制是协调线程行为的重要手段。了解和正确使用中断机制对于编写高效、可靠的并发程序至关重要。本文将深入探讨Java中的`Thread.interrupted()`和`Thread.isInterrupted()`方法的区别及其应用场景。
57 4
|
2月前
|
Java 数据处理 数据安全/隐私保护
Java处理数据接口方法
Java处理数据接口方法
27 1
|
3月前
|
Java API
Java 对象释放与 finalize 方法
关于 Java 对象释放的疑惑解答,以及 finalize 方法的相关知识。
62 17
|
2月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
139 4
|
2月前
|
Java 大数据 API
14天Java基础学习——第1天:Java入门和环境搭建
本文介绍了Java的基础知识,包括Java的简介、历史和应用领域。详细讲解了如何安装JDK并配置环境变量,以及如何使用IntelliJ IDEA创建和运行Java项目。通过示例代码“HelloWorld.java”,展示了从编写到运行的全过程。适合初学者快速入门Java编程。
|
2月前
|
Java 测试技术 Maven
Java一分钟之-PowerMock:静态方法与私有方法测试
通过本文的详细介绍,您可以使用PowerMock轻松地测试Java代码中的静态方法和私有方法。PowerMock通过扩展Mockito,提供了强大的功能,帮助开发者在复杂的测试场景中保持高效和准确的单元测试。希望本文对您的Java单元测试有所帮助。
319 2
|
2月前
|
SQL Rust Java
Java 8 异步编程利器:CompletableFuture
Java 8引入了CompletableFuture,这是一个强大的异步编程工具,增强了Future的功能,支持链式调用、任务组合与异常处理等特性,使异步编程更加直观和高效。本文详细介绍了CompletableFuture的基本概念、用法及高级功能,帮助开发者更好地掌握这一工具。