这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战
CompletableFuture<T>
是java8
中新增的一个类,是对Future<T>
接口的一种增强,可以帮助我们简化异步编程的复杂性,并且提供了函数式编程的能力,可以通过回调的方式处理计算结果
CompletableFuture<T>
类实现了Future<T>
, CompletionStage<T>
CompletionStage<T>
代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段
1.runAsync
和supplyAsync
public static CompletableFuture<Void> runAsync(Runnable runnable)
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)
没有指定Executor
的方法会使用ForkJoinPool.commonPool()
作为它的线程池执行异步代码。如果指定线程池,则使用指定的线程池运行。以下所有的方法都类同。
// 不带返回值
CompletableFuture<Void> completable1 = CompletableFuture.runAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("runAsync is end!");
});
// 带返回值
CompletableFuture<Integer> completable2 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("supplyAsync is end!");
return 10;
});
计算结果完成时回调方法
public CompletableFuture<T> whenComplete(BiConsumer<? super T,? super Throwable> action)
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action)
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action, Executor executor)
public CompletableFuture<T> exceptionally(Function<Throwable,? extends T> fn)
whenComplete
:是执行当前任务的线程执行继续执行whenComplete
的任务whenCompleteAsync
:是执行把whenCompleteAsync
这个任务继续提交给线程池来进行执行。exceptionally
:执行失败后调用
案例:
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<Integer> completable1 = CompletableFuture.supplyAsync(() -> {
int result = 100 / 2;
System.out.println("supplyAsync is end!");
return 10;
});
completable1.whenComplete((r, e) -> {
System.out.println("completable1 is run end");
});
CompletableFuture<Integer> completable2 = CompletableFuture.supplyAsync(() -> {
return 1 / 0;
});
CompletableFuture<Integer> completable3 = completable2.exceptionally((e) -> {
System.out.println("执行任务报错了:" + e.getMessage());
return 0;
});
Integer result = completable3.get();
System.out.println("result:" + result);
}
输出结果
supplyAsync is end!
completable1 is run end
执行任务报错了:java.lang.ArithmeticException: / by zero
result:0
2.thenApply
当一个线程依赖另一个线程时,可以使用 thenApply
方法来把这两个线程串行化。
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
CompletableFuture<Integer> completable1 = CompletableFuture.supplyAsync(() -> {
System.out.println("supplyAsync is end!");
return 10;
}, executorService).thenApply((r) -> {
return r + 10;
});
Integer result = completable1.get();
System.out.println("result:" + result);
}
输出结果
supplyAsync is end!
result:20
3.handle
handle
是执行任务完成时对结果的处理。
handle
方法和 thenApply
方法处理方式基本一样。不同的是 handle
是在任务完成后再执行,还可以处理异常的任务。thenApply
只可以执行正常的任务,任务出现异常则不执行 thenApply
方法
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
CompletableFuture<Integer> completable1 = CompletableFuture.supplyAsync(() -> {
System.out.println("supplyAsync is end!");
int result = 1 / 0;
return 10;
}, executorService).handle((p, e) -> {
if (e != null) {
System.out.println("supplyAsync run is error " + e.getMessage());
return -1;
}
return p + 10;
});
Integer result = completable1.get();
System.out.println("result:" + result);
executorService.shutdown();
}
当任务运行出现异常时 打印异常信息 然后返回-1
输出结果
supplyAsync is end!
supplyAsync run is error java.lang.ArithmeticException: / by zero
result:-1
4. thenAccept
接收任务的处理结果,并消费处理,无返回结果。
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
CompletableFuture<Void> completableFuture1 = CompletableFuture.supplyAsync(() -> {
System.out.println("supplyAsync is end!");
return 10;
}, executorService).thenAccept(System.out::println);
completableFuture1.get();
executorService.shutdown();
}
当任务运行结束后 调用thenAccept
方法消费任务的返回结果
输出结果
supplyAsync is end!
10