CompletableFuture
是 Java 8 引入的一个类,它提供了一种以非阻塞方式处理异步编程的方式。CompletableFuture
可以用来编写更简洁和更灵活的异步代码。
CompletableFuture
概述
CompletableFuture
是 Future
的一个扩展,提供了更丰富的功能,尤其是在处理异步计算时。它允许我们在未来某个时间点计算结果,并且可以在计算完成后继续处理结果。与传统的 Future
不同,CompletableFuture
提供了更强大的链式操作能力和异常处理机制。
主要特性
- 异步计算: 支持非阻塞的异步计算,可以通过
thenApply
,thenAccept
,thenRun
等方法对计算结果进行处理。 - 组合多个计算: 通过
thenCombine
,thenCompose
,allOf
,anyOf
等方法组合多个异步计算。 - 异常处理: 提供了
exceptionally
,handle
等方法来处理异步计算中的异常。 - 超时控制: 可以设置超时时间来限制异步计算的时间。
常用方法
supplyAsync(Supplier<U> supplier)
: 异步执行一个Supplier
提供的任务,并返回一个CompletableFuture
。runAsync(Runnable runnable)
: 异步执行一个Runnable
任务,返回一个CompletableFuture
。thenApply(Function<? super T, ? extends U> fn)
: 在CompletableFuture
完成后对结果进行转换。thenAccept(Consumer<? super T> action)
: 在CompletableFuture
完成后对结果执行某个操作。thenRun(Runnable action)
: 在CompletableFuture
完成后执行某个操作,不使用计算结果。handle(BiFunction<? super T, Throwable, ? extends U> fn)
: 在CompletableFuture
完成后处理结果或异常。exceptionally(Function<Throwable, ? extends T> fn)
: 处理计算过程中出现的异常。allOf(CompletableFuture<?>... cfs)
: 等待所有CompletableFuture
完成。anyOf(CompletableFuture<?>... cfs)
: 等待任意一个CompletableFuture
完成。
应用场景
- 并行处理任务: 当需要并行执行多个独立的任务时,可以使用
CompletableFuture
来处理。 - 异步 API 调用: 调用异步 API,并在调用完成后处理结果或异常。
- 任务链式处理: 需要根据前一个任务的结果执行下一个任务的场景。
- 超时处理: 对异步操作设置超时控制,避免因操作时间过长导致的阻塞。
示例代码
基本用法
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
// 异步计算一个结果
CompletableFuture.supplyAsync(() -> {
// 模拟长时间计算
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
return "Hello";
})
.thenApply(result -> result + " World") // 处理结果
.thenAccept(result -> System.out.println("Final result: " + result)) // 打印结果
.exceptionally(ex -> {
System.err.println("Exception: " + ex.getMessage());
return null;
});
}
}
组合任务
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureCombineExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }
return 10;
});
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }
return 20;
});
// 组合两个 CompletableFuture
CompletableFuture<Integer> combinedFuture = future1.thenCombine(future2, (result1, result2) -> result1 + result2);
// 获取最终结果
Integer result = combinedFuture.get();
System.out.println("Combined result: " + result);
}
}
异常处理
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExceptionHandling {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("Something went wrong");
})
.thenApply(result -> {
return "Result: " + result;
})
.exceptionally(ex -> {
System.err.println("Exception occurred: " + ex.getMessage());
return "Default result";
})
.thenAccept(result -> System.out.println("Final result: " + result));
}
}