CompletableFuture到底怎么用?
CompletableFuture 提供了强大的功能来处理异步编程任务。CompletableFuture
它同时实现了Future
和CompletionStage
两个接口。
1. 创建异步任务
- CompletableFuture.supplyAsync(),支持返回值。
- CompletableFuture.runAsync(),不支持返回值。
// 可以自定义线程池
ExecutorService executor = Executors.newCachedThreadPool();
// runAsync的使用
CompletableFuture<Void> runFuture = CompletableFuture.runAsync(() -> System.out.println("run,关注公众号:捡田螺的小男孩"), executor);
// supplyAsync的使用
CompletableFuture<String> supplyFuture = CompletableFuture.supplyAsync(() -> {System.out.print("supply,关注公众号:捡田螺的小男孩");return "捡田螺的小男孩"; }, executor);
2. 获取返回结果
- CompletableFuture.join(),如果异步操作尚未完成,
get()
方法会阻塞当前线程直到操作完成。join()
不会抛出InterruptedException
。如果当前线程在等待期间被中断,join()
会将中断状态设置回线程,但不抛出异常。 - CompletableFuture.get(),如果异步操作尚未完成,
get()
方法会阻塞当前线程直到操作完成。如果异步操作失败,get()
方法会抛出ExecutionException
来包装原始的异常。
// runAsync的future没有返回值,输出null
System.out.println(runFuture.join());
// supplyAsync的future,有返回值
System.out.println(supplyFuture.join());
3. 异步任务的回调
- CompletableFuture.thenRun/thenRunAsync(),在异步操作完成后同步/异步执行一个无入参、无返回值的操作。
CompletableFuture<String> orgFuture = CompletableFuture.supplyAsync(()->{System.out.println("先执行第一个CompletableFuture方法任务");return "捡田螺的小男孩";}
);CompletableFuture thenRunFuture = orgFuture.thenRun(() -> {System.out.println("接着执行第二个任务");
});
- CompletableFuture.thenAccept/thenApplyAsync(),在异步操作完成后同步/异步执行一个有入参、有返回值的操作。
CompletableFuture<String> orgFuture = CompletableFuture.supplyAsync(()->{System.out.println("原始CompletableFuture方法任务");return "捡田螺的小男孩";}
);CompletableFuture<String> thenApplyFuture = orgFuture.thenApply((a) -> {if ("捡田螺的小男孩".equals(a)) {return "关注了";}return "先考虑考虑";
});
- CompletableFuture.exceptionally(),用于处理异步操作中的异常。
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {if (Math.random() > 0.5) {throw new RuntimeException("Operation failed!");}return 42;
}).exceptionally(throwable -> {// 异常处理逻辑System.out.println("Handling exception: " + throwable.getMessage());// 返回一个替代的结果return -1;
});System.out.println("Future result: " + future.join()); // 如果有异常,输出将是 -1
4. 异步任务的组合操作
- CompletableFuture.thenCombine/thenCombineAsync(),用于将两个异步操作的结果组合起来。
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (s1, s2) -> s1 + ", " + s2);
System.out.println(combinedFuture.join()); // 输出 "Hello, World"
- CompletableFuture.thenCompose/thenComposeAsync(),用于在异步操作完成后,将结果传递给另一个异步操作。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello").thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " World"));
System.out.println(future.join());
- CompletableFuture.allOf(),等待多个
CompletableFuture
都完成。
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> "!");CompletableFuture<Void> allFuture = CompletableFuture.allOf(future1, future2, future3);
allFuture.thenRun(() -> System.out.println("Both futures are complete."));
- CompletableFuture.anyOf(),等待多个
CompletableFuture
任意一个完成。
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> "!");CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(future1, future2, future3);
anyFuture.thenAccept(completedFuture -> System.out.println("One of the futures is complete."));