使用 CompletableFuture 进行异步编程
CompletableFuture
是 Java 8 引入的一个类,用于简化异步编程。它提供了丰富的 API,用于创建、组合和处理异步任务。本文将详细介绍 CompletableFuture
的常用方法,并通过实例演示其强大功能。
1. 创建 CompletableFuture
supplyAsync
supplyAsync
方法用于异步地执行一个 Supplier
,返回一个 CompletableFuture
。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) {
//存在返回值,后续操作可使用
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
return "Hello, World!";
});
future.thenAccept(System.out::println); // 输出: Hello, World!
}
}
runAsync
runAsync
方法用于异步地执行一个 Runnable
,返回一个 CompletableFuture<Void>
。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) {
//无返回值
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
System.out.println("Hello, World!");
});
future.join(); // 确保主线程等待异步任务完成
}
}
2. 组合多个 CompletableFuture
thenApply
thenApply
方法用于在当前 CompletableFuture
完成后应用一个函数并返回一个新的 CompletableFuture
。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 1)
.thenApply(result -> result + 1);
future.thenAccept(System.out::println); // 输出: 2
}
}
thenAccept
thenAccept
方法用于在当前 CompletableFuture
完成后应用一个消费者,无返回值。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> "Hello, World!")
.thenAccept(result -> System.out.println(result)); // 输出: Hello, World!
}
}
thenRun
thenRun
方法用于在当前 CompletableFuture
完成后执行一个 Runnable
。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> "Hello, World!")
//不接收上个函数的返回值
.thenRun(() -> System.out.println("Task completed")); // 输出: Task completed
}
}
3. 处理多个 CompletableFuture
thenCombine
thenCombine
方法用于组合两个 CompletableFuture
,并在它们都完成后应用一个函数。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) {
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 2);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 3);
CompletableFuture<Integer> combinedFuture = future1.thenCombine(future2, (result1, result2) -> result1 + result2);
combinedFuture.thenAccept(System.out::println); // 输出: 5
}
}
thenCompose
thenCompose
方法用于在当前 CompletableFuture
完成后应用一个函数,该函数返回一个新的 CompletableFuture
。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> "Hello")
//内部执行一个函数
// 与thenApply的不同之处
//函数的返回值不同,thenApply Function<? super T,? extends U> fn
// thenCompose Function<? super T, ? extends CompletionStage<U>> fn
.thenCompose(result -> CompletableFuture.supplyAsync(() -> result + ", World!"))
.thenAccept(System.out::println); // 输出: Hello, World!
}
}
4. 处理异常
exceptionally
exceptionally
方法用于处理当前 CompletableFuture
异常完成的情况。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
if (true) throw new RuntimeException("Error!");
return "Hello, World!";
}).exceptionally(ex -> "Hello, Fallback!")
.thenAccept(System.out::println); // 输出: Hello, Fallback!
}
}
handle
handle
方法用于在当前 CompletableFuture
完成或异常完成时应用一个函数。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
if (true) throw new RuntimeException("Error!");
return "Hello, World!";
}).handle((result, ex) -> {
if (ex != null) return "Hello, Fallback!";
return result;
}).thenAccept(System.out::println); // 输出: Hello, Fallback!
}
}
5. 等待所有任务完成
allOf
allOf
方法用于等待所有提供的 CompletableFuture
完成。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) {
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> System.out.println("Task 1 completed"));
CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> System.out.println("Task 2 completed"));
CompletableFuture<Void> future3 = CompletableFuture.runAsync(() -> System.out.println("Task 3 completed"));
CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2, future3);
allOf.thenRun(() -> System.out.println("All tasks completed"));
allOf.join(); // 确保主线程等待所有异步任务完成
}
}
6. 任意一个任务完成
anyOf
anyOf
方法用于等待任一提供的 CompletableFuture
完成。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) {
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(100); } catch (InterruptedException e) { }
return "Task 1 completed";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Task 2 completed");
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> "Task 3 completed");
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future1, future2, future3);
anyOf.thenAccept(result -> System.out.println("One of the tasks completed: " + result));
anyOf.join(); // 确保主线程等待任一异步任务完成
}
}
7. 获取结果
join
join
方法用于获取 CompletableFuture
的结果,如果任务未完成会阻塞等待。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) {
String result = CompletableFuture.supplyAsync(() -> "Hello, World!").join();
System.out.println(result); // 输出: Hello, World!
}
}
get
get
方法用于获取 CompletableFuture
的结果,可能会抛出异常。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) {
try {
String result = CompletableFuture.supplyAsync(() -> "Hello, World!").get();
System.out.println(result); // 输出: Hello, World!
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
总结
CompletableFuture
提供了强大的异步编程能力,简化了异步任务的创建和组合。通过了解和使用这些方法,可以更轻松地编写高效且可维护的异步代码。希望本文的介绍和示例对您有所帮助。