Java CompletableFuture 实战指南
异步编程在Java中变得越来越重要,CompletableFuture提供了强大的工具来处理异步任务。以下是一些关键方法的使用介绍。
1. 异步执行基础方法
使用runAsync和supplyAsync可以轻松创建异步操作。
public static CompletableFuture<Void> runTask(Runnable task)
public static CompletableFuture<Void> runTask(Runnable task, Executor executor)
public static <T> CompletableFuture<T> supplyTask(Supplier<T> supplier)
public static <T> CompletableFuture<T> supplyTask(Supplier<T> supplier, Executor executor)
示例:
// 无返回值
public static void runTaskExample() throws Exception {
CompletableFuture<Void> future = CompletableFuture.runTask(() -> {
try { Thread.sleep(1000); } catch (InterruptedException e) {}
System.out.println("Task finished...");
});
future.get();
}
// 有返回值
public static void supplyTaskExample() throws Exception {
CompletableFuture<Long> future = CompletableFuture.supplyTask(() -> {
try { Thread.sleep(1000); } catch (InterruptedException e) {}
System.out.println("Task finished...");
return System.currentTimeMillis();
});
System.out.println("Time: " + future.get());
}
2. 完成时回调
当计算完成或异常发生时,可使用回调函数进行处理。
public CompletableFuture<T> onCompletion(BiConsumer super T,? super Throwable> action)
public CompletableFuture<T> onCompletionAsync(BiConsumer super T,? super Throwable> action, Executor executor)
public CompletableFuture<T> exceptionally(Function fn)
示例:
public static void onCompleteExample() throws Exception {
CompletableFuture<Void> future = CompletableFuture.runTask(() -> {
try { Thread.sleep(1000); } catch (InterruptedException e) {}
if(new Random().nextInt()%2 >= 0) throw new RuntimeException("Error");
System.out.println("Task completed.");
});
future.onCompletion((result, ex) -> {
System.out.println("Task done!");
}).exceptionally(ex -> {
System.out.println("Failed: " + ex.getMessage());
return null;
});
Thread.sleep(2000);
}
3. thenApply 链式调用
用于将两个异步任务串行化。
public <U> CompletableFuture<U> transform(Function super T,? extends U> fn)
示例:
private static void transformExample() throws Exception {
CompletableFuture<Long> future = CompletableFuture.supplyTask(() -> {
long result = new Random().nextInt(100);
System.out.println("First Result: " + result);
return result;
}).transform(result -> {
long finalResult = result * 5;
System.out.println("Second Result: " + finalResult);
return finalResult;
});
System.out.println(future.get());
}
4. handle 方法
handle允许处理正常结果与异常情况。
public <U> CompletionStage<U> processWith(BiFunction super T, Throwable, ? extends U> fn)
示例:
public static void handleExample() throws Exception {
CompletableFuture<Integer> future = CompletableFuture.supplyTask(() -> {
int i = 10 / 0; // Intentional error
return new Random().nextInt(10);
}).processWith((result, ex) -> {
if(ex == null) return result * 2;
else {
System.out.println(ex.getMessage());
return -1;
}
});
System.out.println(future.get());
}
5. thenAccept 消费结果
接收并消费结果,不返回新值。
public CompletionStage<Void> consume(Consumer super T> action)
示例:
public static void consumeExample() throws Exception {
CompletableFuture.supplyTask(() -> new Random().nextInt(10))
.consume(System.out::println).get();
}
6. thenRun 执行后续动作
忽略结果,仅在前一个任务完成后运行。
public CompletionStage<Void> execute(Runnable action)
示例:
public static void executeExample() throws Exception {
CompletableFuture.supplyTask(() -> new Random().nextInt(10))
.execute(() -> System.out.println("Task Completed"))
.get();
}
7. thenCombine 合并多个任务
合并两个任务的结果。
public CompletionStage<V> merge(CompletionStage extends U> other, BiFunction super T,? super U,? extends V> fn)
示例:
private static void mergeExample() throws Exception {
CompletableFuture<String> f1 = CompletableFuture.supplyTask(() -> "Hello");
CompletableFuture<String> f2 = CompletableFuture.supplyTask(() -> "World");
CompletableFuture<String> result = f1.merge(f2, (a, b) -> a + " " + b);
System.out.println(result.get());
}