【异步函数式编程】CompletableFuture用法(二)

继上章节(传送门>>>),本章继续介绍CompletableFuture其余方法的使用。java

public static void main(String[] args) throws Exception {
    // 6. 回调2.0【whenComplete,handle】
    CompletableFuture<String> cf4 = CompletableFuture.supplyAsync(() -> {
        System.out.println("6.业务过程=" + 1 / 1);
        // System.out.println("6.业务过程=" + 1 / 0);
        return "cf4正常执行返回";
    }).whenComplete((result, exce) -> {
        if (null != exce) {
            // exce.printStackTrace();
            System.out.println("异常信息=" + exce.getMessage());
        } else {
            System.out.println("6.回调2.0正常执行返回");
        }
    });
    System.out.println(cf4.get());
    /** * 注: 和以前回调应用场景的区别 * 1.cf4任务是正常执行的,cf4.get()的结果就是cf4执行的结果 * 2.cf4任务是执行异常的,则cf4.get()会抛出异常 * * handle与whenComplete用法相似,区别: * 1:handle有返回值,whenComplete无返回值 * 2:handle有返回值且与cf4自身的返回无任何关系 */

    // 7.组合处理(1)【thenCombine、thenAcceptBoth、runAfterBoth】
    /** * 三个方法都是将两个CompletableFuture组合起来,两个都正常执行完了才会执行某个任务 * 区别: * 1:thenCombine会将两个任务的返回值做为入参传递到目标方法中,且目标方法有返回值 * 2:thenAcceptBoth一样将两个任务的返回值做为目标方法入参,但目标方法无返回值 * 3:runAfterBoth没有入参,也没有返回值 */
    CompletableFuture<String> cf5_1 = CompletableFuture.supplyAsync(() -> {
        // 任务1
        return "cf5_1返回";
    });
    CompletableFuture<String> cf5_2 = CompletableFuture.supplyAsync(() -> {
        // 任务2
        return "cf5_2返回";
    });

    CompletableFuture<String> cf5_thenCombine = cf5_1.thenCombine(cf5_2, (a, b) -> {
        // 有返回
        return "7.组合处理【thenCombine】=" + a + " -- " + b;
    });
    System.out.println(cf5_thenCombine.get());

    CompletableFuture<Void> cf5_thenAcceptBoth = cf5_1.thenAcceptBoth(cf5_2, (a, b) -> {
        // 无返回
        System.out.println("7.组合处理【thenAcceptBoth】=" + a + " -- " + b);
    });
    cf5_thenAcceptBoth.get();
    CompletableFuture<Void> cf5_runAfterBoth = cf5_1.runAfterBoth(cf5_2, () -> {
        // 无入参,无返回
        System.out.println("7.组合处理【runAfterBoth】=" + "无入参,无返回");
    });
    cf5_runAfterBoth.get();

    // 7.组合处理(2)【applyToEither、acceptEither、runAfterEither】
    /** * 三个方法都是将两个CompletableFuture组合起来,只要其中一个执行完了就会执行目标任务 * 区别: * 1:applyToEither会将已经执行完成的任务的执行结果做为方法入参,并有返回值; * 2:acceptEither一样将已经执行完成的任务的执行结果做为方法入参,可是没有返回值 * 3:runAfterEither没有方法入参,也没有返回值 */
    // 7.组合处理(1)和7.组合处理(2)的区别在于,执行目标任务的前提,前者必须所有正常执行,后者有一个执行完成

    // 8.【allOf、anyOf】
    CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        return "Task1";
    });
    CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
        }
        return "Task2";
    });
    CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> {
        try {
            Thread.sleep(2500);
        } catch (InterruptedException e) {
        }
        return "Task3";
    });

    // 能够相似实现countdownLatch的功能,实现阻塞线程,等待子任务执行完成
    CompletableFuture<Void> cf6 = CompletableFuture.allOf(task1, task2, task3);
// System.out.println(cf6.get(20, TimeUnit.MILLISECONDS));
    System.out.println("cf6.get()=" + cf6.get());
    /** * 区别: * 1:allof等待全部任务执行完成才执行cf6 * 2:anyOf是只有一个任务执行完成,不管是正常执行或者执行异常,都会执行cf6 */
    // allof:若是有一个任务异常终止,则cf6.get时会抛出异常,都是正常执行,cf6.get返回null
    // anyOf:cf6.get的结果就是已执行完成的任务的执行结果
}
复制代码

执行结果如图:markdown

image.png 欢迎评论区指正和交流。app

相关文章
相关标签/搜索