CompletableFuture高级用法之一
CompletableFuture
是 Java 中用于异步编程的一个强大工具。它位于 java.util.concurrent
包中,实现了 Future
和 CompletionStage
接口。它有很多方法容易弄混,在这里列出以澄清。
get
和join
的方法区别如下:
方法名称 | 作用描述 |
---|---|
get() | 等待CompletableFuture 执行完成并获取其具体执行结果,可能会抛出异常,需要代码调用的地方手动try...catch 进行处理。 |
get(long, TimeUnit) | 与get()相同,只是允许设定阻塞等待超时时间,如果等待超过设定时间,则会抛出异常终止阻塞等待。 |
join() | 等待CompletableFuture 执行完成并获取其具体执行结果,可能会抛出运行时异常,无需代码调用的地方手动try...catch进行处理。 |
- 异常情况处理
-
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
-
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
-
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 类中用于组合异步操作的方法,但它们有不同的用途和行为。
- 使用 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());
}
}
- 使用 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