likes
comments
collection
share

CompletableFuture高级用法之一

作者站长头像
站长
· 阅读数 6

CompletableFuture 是 Java 中用于异步编程的一个强大工具。它位于 java.util.concurrent 包中,实现了 Future 和 CompletionStage 接口。它有很多方法容易弄混,在这里列出以澄清。

  • getjoin的方法区别如下:
方法名称作用描述
get()等待CompletableFuture执行完成并获取其具体执行结果,可能会抛出异常,需要代码调用的地方手动try...catch进行处理。
get(long, TimeUnit)与get()相同,只是允许设定阻塞等待超时时间,如果等待超过设定时间,则会抛出异常终止阻塞等待。
join()等待CompletableFuture执行完成并获取其具体执行结果,可能会抛出运行时异常,无需代码调用的地方手动try...catch进行处理。
  • 异常情况处理
  1. handle()handle() 方法允许你在任务完成(无论正常完成还是出现异常)后对结果进行处理。它接受一个 BiFunction 参数,该函数会在任务完成时被调用,可以处理结果或异常。不会将异常外抛。

    Java

    CompletableFuture<Integer> divide(int a, int b) {
        return CompletableFuture.supplyAsync(() -> a / b)
            .handle((result, ex) -> {
                if (ex != null) {
                    System.out.println(ex.getMessage());
                    return 0;
                } else {
                    return result;
                }
            });
    }
    
    try {
        System.out.println("成功结果:" + divide(6, 3).get());
        System.out.println("异常结果:" + divide(6, 0).get());
    } catch (Exception exception) {
        System.out.println("捕获到异常:" + exception.getMessage());
    }
    

    输出结果:

    成功结果:2
    java.lang.ArithmeticException: / by zero
    异常结果:0
    
  2. whenComplete()whenComplete() 方法允许你访问当前 CompletableFuture 的结果和异常作为参数,并执行你想要的操作。它不会转换完成的结果,但会在内部处理异常。

    Java

    CompletableFuture<Integer> whenComplete(int a, int b) {
        return CompletableFuture.supplyAsync(() -> a / b)
            .whenComplete((result, ex) -> {
                if (ex != null) {
                    System.out.println("whenComplete 处理异常:" + ex.getMessage());
                }
            });
    }
    
    try {
        System.out.println("成功结果:" + whenComplete(6, 3).get());
        System.out.println("异常结果:" + whenComplete(6, 0).get());
    } catch (Exception exception) {
        System.out.println("捕获到异常:" + exception.getMessage());
    }
    

    输出:

    成功结果:2
    whenComplete 处理异常:java.lang.ArithmeticException: / by zero
    
  3. exceptionally()exceptionally() 方法仅处理异常情况,即发生异常时执行。如果可完成的未来成功完成,内部逻辑将被跳过,不会将内部异常抛出。

    Java

    CompletableFuture<Integer> exceptionally(int a, int b) {
        return CompletableFuture.supplyAsync(() -> a / b)
            .exceptionally(ex -> {
                System.out.println("exceptionally 处理异常:" + ex.getMessage());
                return 0;
            });
    }
    
    try {
        System.out.println("成功结果:" + exceptionally(6, 3).get());
        System.out.println("异常结果:" + exceptionally(6, 0).get());
    } catch (Exception exception) {
        System.out.println("捕获到异常:" + exception.getMessage());
    }
    

    输出:

    成功结果:2
    exceptionally 处理异常:java.lang.ArithmeticException: / by zero
    **```**
    
  • thenCompose 和 thenCombine的方法区别如下:

thenCompose 和 thenCombine 都是 CompletableFuture 类中用于组合异步操作的方法,但它们有不同的用途和行为。

  1. 使用 thenCompose 连接异步任务时,通常用于处理异步任务的返回值作为下一个任务的输入。
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> divide(int a, int b) {
            return CompletableFuture.supplyAsync(() -> a / b)
                .thenCompose(result -> CompletableFuture.supplyAsync(() -> {
                    // Perform additional processing using the result
                    return result * 2;
                }));
        }

        System.out.println("Result for 6 / 3: " + divide(6, 3).get());
    }
}
  1. 使用 thenCombine 合并两个任务的结果时,不考虑先后顺序,而是并行执行并合并结果
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Dept> getDept = CompletableFuture.supplyAsync(() -> getDeptById(1));
        CompletableFuture<User> getUser = CompletableFuture.supplyAsync(() -> getUserById(1));

        CompletableFuture<User> combinedResult = getDept.thenCombine(getUser, (dept, user) -> {
            // Combine results from both tasks
            user.setDeptId(dept.getId());
            user.setDeptName(dept.getName());
            return user;
        });

        System.out.println("Combined result: " + combinedResult.get());
    }
}
转载自:https://juejin.cn/post/7347668434447351818
评论
请登录