Java中的CompletableFuture使用文档
1. 引言
在现代软件开发中,异步编程已经成为处理高并发和响应式系统的关键技术之一。Java 8引入了CompletableFuture
,这是一种功能强大且灵活的异步编程API,它扩展了Future
接口,提供了许多新的特性,使得编写非阻塞式的异步代码更加容易。本文档旨在介绍CompletableFuture
的基础知识及其高级用法,帮助开发者更好地理解和应用这一工具。
2. CompletableFuture简介
CompletableFuture
是java.util.concurrent
包下的一个类,它代表了一个可能会在将来完成的计算的结果。它可以用来异步地执行任务,并且提供了一种优雅的方式来处理这些任务的结果、异常和组合多个任务。
3. 创建CompletableFuture
3.1 使用静态工厂方法
CompletableFuture
提供了几个静态工厂方法来创建不同的CompletableFuture
实例:
supplyAsync(Supplier<T> supplier)
:创建一个异步完成的CompletableFuture
,使用默认的ForkJoinPool.commonPool()
来执行supplier
。
runAsync(Runnable runnable)
:创建一个异步执行的CompletableFuture
,不返回任何结果。
completedFuture(V value)
:创建一个已完成的CompletableFuture
,立即返回给定的结果值。
示例:
1 2 3 4 5 6 7 8
| import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample { public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello CompletableFuture!"); CompletableFuture<Void> runFuture = CompletableFuture.runAsync(() -> System.out.println("Running async task")); } }
|
3.2 使用构造器
你也可以通过CompletableFuture
的构造器来创建实例,并且手动完成它。
示例:
1 2 3 4 5 6 7 8 9
| import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample { public static void main(String[] args) { CompletableFuture<String> future = new CompletableFuture<>(); future.complete("Hello CompletableFuture!"); } }
|
4. 处理CompletableFuture的结果
4.1 thenApply
thenApply
方法可以用于在前一个阶段完成后执行另一个任务,并且该任务可以访问前一阶段的结果。
示例:
1 2 3 4 5 6 7 8
| import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample { public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello CompletableFuture!") .thenApply(result -> result.toUpperCase()); } }
|
4.2 thenAccept
thenAccept
方法用于在前一个阶段完成后执行一个消费型操作,它不会返回任何结果。
示例:
1 2 3 4 5 6 7 8
| import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample { public static void main(String[] args) { CompletableFuture.supplyAsync(() -> "Hello CompletableFuture!") .thenAccept(result -> System.out.println("Received result: " + result)); } }
|
4.3 thenRun
thenRun
方法用于在前一个阶段完成后执行一个Runnable任务,它不依赖于前一阶段的结果。
示例:
1 2 3 4 5 6 7 8
| import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample { public static void main(String[] args) { CompletableFuture.supplyAsync(() -> "Hello CompletableFuture!") .thenRun(() -> System.out.println("Task completed")); } }
|
5. 处理异常
5.1 exceptionally
exceptionally
方法用于处理前一阶段抛出的异常。
示例:
1 2 3 4 5 6 7 8 9 10 11 12
| import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample { public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Oops, something went wrong!"); }).exceptionally(ex -> { System.err.println("Caught exception: " + ex.getMessage()); return "Error occurred"; }); } }
|
5.2 handle
handle
方法类似于thenApply
,但它可以处理正常结果和异常两种情况。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample { public static void main(String[] args) { CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Oops, something went wrong!"); }).handle((result, ex) -> { if (ex == null) { return result; } else { System.err.println("Caught exception: " + ex.getMessage()); return "Error occurred"; } }); } }
|
6. 组合多个CompletableFuture
6.1 allOf
allOf
方法用于等待一组CompletableFuture
全部完成。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample { public static void main(String[] args) throws Exception { CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Result 1"); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Result 2");
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2); combinedFuture.get();
System.out.println(future1.get()); System.out.println(future2.get()); } }
|
6.2 anyOf
anyOf
方法用于等待一组CompletableFuture
中的任何一个完成。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample { public static void main(String[] args) throws Exception { CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e); } return "Result 1"; });
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Result 2");
CompletableFuture<Object> combinedFuture = CompletableFuture.anyOf(future1, future2); Object result = combinedFuture.get();
System.out.println("First completed result: " + result); } }
|
7. 同步与异步
尽管CompletableFuture
的主要用途是处理异步任务,但它也提供了同步的方法来获取结果,如get()
方法。然而,get()
方法会阻塞当前线程直到结果可用,因此在多线程环境中应谨慎使用。
8. 使用自定义执行器
你可以通过传递一个Executor
参数给supplyAsync
或runAsync
方法来指定一个自定义的线程池。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;
public class CompletableFutureExample { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(5);
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello CompletableFuture!", executor);
executor.shutdown(); } }
|
9. 总结
通过上述示例,你应该对CompletableFuture
有了初步的了解,并且知道如何使用它来进行异步编程。CompletableFuture
不仅简化了异步编程模型,还提供了强大的组合功能,使得异步编程变得更加简洁和高效。希望这份文档能帮助你在实际项目中更好地利用这一工具。