这种实现方法还是不能实现真正的异步编程或者说不是我们所期望的,我们期望的是登录后获取用户信息,但这两件事情完成后统一对结果进行处理,而这种方式是先等待登录之后再取用户信息,和同步调用类似,这就与我们的设想不符。
在Java8中引入了CompletableFuture类,同时实现了Future接口和CompletionStage接口,提供了一套用于异步编程的Api接口并且提供了异步处理
CompletableFuture提供了许多异步编程的操作,可以说是Java中的Promise了,下面通过CompletableFuture来实现上面提到的例子:
String userInfo = CompletableFuture.supplyAsync(() -> login())
.thenApplyAsync(token -> userInfo(token))
.get();
System.out.println(userInfo);
CompletableFuture方法很多,功能也很丰富,这里不一一说明,主要可以分为这几类来使用:
CompletableFuture实现了Future接口,也就是Future能做的CompletableFuture也同样能使用,加上complete和completeExceptionally方法可以控制结果的结束:
CompletableFuture f = new CompletableFuture<>();
Executors.newSingleThreadExecutor().submit(()->{
f.complete(“hello”);
//f.completeExceptionally(new RuntimeException(“error”));
});
String result = f.get();
System.out.println(result);
可以通过CompletableFuture来控制多个异步操作同时执行:
CompletableFuture f = new CompletableFuture<>();
new Thread(() -> {
try {
System.out.println(“thread1:” + f.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
System.out.println(“thread2:” + f.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}).start();
f.complete(“hello”);
创建异步操作的方法主要是:
public static CompletableFuture runAsync(Runnable runnable)
public static CompletableFuture runAsync(Runnable runnable,Executor executor)
public static CompletableFuture supplyAsync(Supplier supplier)
public static CompletableFuture supplyAsync(Supplier supplier,Executor executor)
使用如下:
CompletableFuture f = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return “hello”;
});
String result = f.get();
System.out.println(result);
public CompletableFuture thenRun(Runnable action)
public CompletableFuture thenRunAsync(Runnable action)
public CompletableFuture thenRunAsync(Runnable action,Executor executor)
public CompletableFuture thenApply(Function<? super T,? extends U> fn)
public CompletableFuture thenApplyAsync(Function<? super T,? extends U> fn)
public CompletableFuture thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
public CompletableFuture thenAccept(Consumer<? super T> action)
public CompletableFuture thenAcceptAsync(Consumer<? super T> action)
public CompletableFuture thenAcceptAsync(Consumer<? super T> action,Executor executor)
使用如下:
CompletableFuture f = CompletableFuture
.supplyAsync(() -> “hello”)
.thenApplyAsync(res -> res + " world!")
.thenAcceptAsync(System.out::println);
// wait for job done
f.get();
public CompletableFuture whenComplete(BiConsumer<? super T, ? s
《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享
uper Throwable> action)
public CompletableFuture whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action)
public CompletableFuture whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor)
使用如下:
CompletableFuture f = CompletableFuture
.supplyAsync(() -> “hello”)
.thenApplyAsync(res -> res + " world!")
.whenComplete((res, err) -> {
if (err != null) {
err.printStackTrace();
} else {
System.out.println(res);
}
});
// wait for job done
f.get();
public CompletableFuture thenCompose(Function<? super T, ? extends CompletionStage> fn)
public CompletableFuture thenComposeAsync(Function<? super T, ? extends CompletionStage> fn)
public CompletableFuture thenComposeAsync(Function<? super T, ? extends CompletionStage> fn,Executor executor)
public <U,V> CompletableFuture thenCombine(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn)
public <U,V> CompletableFuture thenCombineAsync(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn)
public <U,V> CompletableFuture thenCombineAsync(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn, Executor executor)
使用如下:
CompletableFuture f = CompletableFuture.supplyAsync(() -> “Hello”)
.thenCompose(res -> CompletableFuture.supplyAsync(() -> res + " World,"))
.thenCombine(CompletableFuture.supplyAsync(() -> “CompletableFuture!”), (a, b) -> a + b);
String result = f.get();
System.out.println(result);//Hello World,CompletableFuture!
public CompletableFuture handle(BiFunction<? super T, Throwable, ? extends U> fn)
public CompletableFuture handleAsync(BiFunction<? super T, Throwable, ? extends U> fn)
public CompletableFuture handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor)
public CompletableFuture exceptionally(Function<Throwable, ? extends T> fn)
使用如下:
// 异常处理
CompletableFuture f = CompletableFuture.supplyAsync(() -> “Hello”)
.thenApplyAsync(res -> res + “World”)
.thenApplyAsync(res -> {
throw new RuntimeException(“error”);
})
.exceptionally(e -> {
//handle exception here
e.printStackTrace();
return null;
});
f.get();
// 执行结果处理
CompletableFuture f2 = CompletableFuture.supplyAsync(() -> “Hello”)
.thenApplyAsync(res -> res + “World”)
.thenApplyAsync(res -> {
throw new RuntimeException(“error”);
})
.handleAsync((res, err) -> {
if (err != null) {
//handle exception here