CompletableFuture类实现了CompletionStage和Future接口。Future是Java 5添加的类,用来描述一个异步计算的结果,但是获取一个结果时方法较少,要么通过轮询isDone,确认完成后,调用get()获取值,要么调用get()设置一个超时时间。但是这个get()方法会阻塞住调用线程,这种阻塞的方式显然和我们的异步编程的初衷相违背。
为了解决这个问题,JDK吸收了guava的设计思想,加入了Future的诸多扩展功能形成了CompletableFuture。CompletableFuture可以在某个线程完成某任务的时候回调某个函数
CompletableFuture 主要API如下
public CompletionStage thenApply(Function super T,? extends U> fn);
public CompletionStage thenApplyAsync(Function super T,? extends U> fn);
public CompletionStage thenApplyAsync(Function super T,? extends U> fn,Executor executor);
例如
public void thenApplay() {
String result = CompletableFuture.supplyAsync(() -> "hello").thenApply(s -> s + " world").join();
System.out.println(result);
}
运行结果为
hello world
public CompletionStage thenAccept(Consumer super T> action);
public CompletionStage thenAcceptAsync(Consumer super T> action);
public CompletionStage thenAcceptAsync(Consumer super T> action,Executor executor);
示例
@Test
public void thenAccept(){
CompletableFuture.supplyAsync(()->"hello").thenAccept(s-> System.out.println(s+" world"));
}
运行结果为
hello world
public CompletionStage thenRun(Runnable action);
public CompletionStage thenRunAsync(Runnable action);
public CompletionStage thenRunAsync(Runnable action,Executor executor);
示例
public void thenRun(){
CompletableFuture.supplyAsync(()->{
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello World";
}).thenRun(()-> System.out.println("Hello World"));
}
运行结果
Hello World
public CompletionStage thenCombine(CompletionStage extends U> other,BiFunction super T,? super U,? extends V> fn);
public CompletionStage thenCombineAsync(CompletionStage extends U> other,BiFunction super T,? super U,? extends V> fn);
public CompletionStage thenCombineAsync(CompletionStage extends U> other,BiFunction super T,? super U,? extends V> fn,Executor executor);
示例
public void thenCombine(){
String result=CompletableFuture.supplyAsync(()->{
return "hello ";
}).thenCombine(CompletableFuture.supplyAsync(()->{
return "world";
}),(s1,s2)->s1+s2).join();
System.out.println(result);
}
运行结果
hello world
public CompletionStage runAfterBoth(CompletionStage> other,Runnable action);
public CompletionStage runAfterBothAsync(CompletionStage> other,Runnable action);
public CompletionStage runAfterBothAsync(CompletionStage> other,Runnable action,Executor executor);
示例
public void thenAfterRun() {
CompletableFuture.supplyAsync(() -> "Hello")
.runAfterBoth(CompletableFuture.supplyAsync(() -> " World"), () -> System.out.println("Hello World"));
}
运行结果
Hello World
public <U> CompletionStage<U> applyToEither(CompletionStage extends T> other,Function super T, U> fn);
public CompletionStage applyToEitherAsync(CompletionStage extends T> other,Function super T, U> fn);
public CompletionStage applyToEitherAsync(CompletionStage extends T> other,Function super T, U> fn,Executor executor);
示例
public void applyToEither(){
String result=CompletableFuture.supplyAsync(()->"hello").applyToEither(CompletableFuture.supplyAsync(()->" World"),s->s).join();
System.out.println(result);
}
运行结果
hello
这个API与上一个API优点像不同点在于上一个API有返回值
public CompletionStage acceptEither(CompletionStage extends T> other,Consumer super T> action);
public CompletionStage acceptEitherAsync(CompletionStage extends T> other,Consumer super T> action);
public CompletionStage acceptEitherAsync(CompletionStage extends T> other,Consumer super T> action,Executor executor);
示例
public void acceptEither(){
CompletableFuture.supplyAsync(()->"Hello")
.acceptEither(CompletableFuture.supplyAsync(()->"World"),System.out::println);
}
运行结果
Hello
public CompletionStage runAfterEither(CompletionStage> other,Runnable action);
public CompletionStage runAfterEitherAsync(CompletionStage> other,Runnable action);
public CompletionStage runAfterEitherAsync(CompletionStage> other,Runnable action,Executor executor);
示例
public void runAfterEigher() {
CompletableFuture.supplyAsync(() -> {
while (true) {
}
}).runAfterEither(CompletableFuture.supplyAsync(() -> "s2"), () -> System.out.println("finish"));
运行结果
finish
public CompletionStage exceptionally(Function fn);
示例
public void exceptionally() {
String result = (String) CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("异常");
}).exceptionally(e -> {
System.out.println(e.getMessage());
return "hello world";
}).join();
System.out.println(result);
}
结果为
java.lang.RuntimeException: 异常
hello world
运行完成时,对结果
public CompletionStage whenComplete(BiConsumer super T, ? super Throwable> action);
public CompletionStage whenCompleteAsync(BiConsumer super T, ? super Throwable> action);
public CompletionStage whenCompleteAsync(BiConsumer super T, ? super Throwable> action,Executor executor);
示例
public void whenComplete() {
String result = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (1 == 1) {
throw new RuntimeException("测试一下异常情况");
}
return "s1";
}).whenComplete((s, t) -> {
System.out.println(s);
System.out.println(t.getMessage());
}).exceptionally(e -> {
System.out.println(e.getMessage());
return "hello world";
}).join();
System.out.println(result);
}
public CompletionStage handle(BiFunction super T, Throwable, ? extends U> fn);
public CompletionStage handleAsync(BiFunction super T, Throwable, ? extends U> fn);
public CompletionStage handleAsync(BiFunction super T, Throwable, ? extends U> fn,Executor executor);
示例
public void handle() {
String result = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//出现异常
if (1 == 1) {
throw new RuntimeException("测试一下异常情况");
}
return "s1";
}).handle((s, t) -> {
if (t != null) {
return "hello world";
}
return s;
}).join();
System.out.println(result);
}
结果为
hello world