CompletableFuture是JDK8提出的一个支持非阻塞的多功能的Future,同样也是实现了Future接口。
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() 作为它的线程池执行异步代码。如果指定线程池,则使用指定的线程池运行。以下所有的方法都类同。
- runAsync方法不支持返回值。
- supplyAsync可以支持返回值。
2、计算结果完成时的回调方法
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)
上面的四种方法都返回了CompletableFuture,当我们Action执行完毕的时候,future返回的值和我们原始的CompletableFuture的值是一样的。上面以Async结尾的会在新的线程池中执行,上面没有一Async结尾的会在之前的CompletableFuture执行的线程中执行。例子代码如下:
3、计算结果完成时的消费(无需返回结果)
上面已经讲了结果完成时的处理和转换,他们最后的CompletableFuture都会返回对应的值,这里还会有一个只会对计算结果消费不会返回任何结果的方法。
public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor)
T:上一个任务返回结果的类型
U:当前任务的返回值类型
当一个线程依赖另一个线程时,可以使用 thenApply 方法来把这两个线程串行化。
- 计算结果完成时的消费(返回结果)
这里同样也是返回CompletableFuture,但是这个结果会由我们自定义返回去转换他,同样的不以Async结尾的方法由原来的线程计算,以Async结尾的方法由默认的线程池ForkJoinPool.commonPool()或者指定的线程池executor运行。
public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class Test1 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
String s = "Lcuy";
Test1 test1 = new Test1();
CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
return s + " ";
}).thenApply(name -> {
System.out.println(name);
return test1.hello(s);
}).thenApply(str -> {
System.out.println(str);
return test1.welcome(str);
});
stringCompletableFuture.thenAccept(System.out::println);
System.out.println(stringCompletableFuture.get());
CompletableFuture.supplyAsync(() -> {
return s + " ";
}).thenApply(name -> {
return test1.hello(s);
}).thenApply(str -> {
return test1.welcome(str);
}).thenAccept(System.out::println);
}
public String hello(String name){
return "Hello,"+name;
}
public String welcome(String str){
return str + ", welcome back.";
}
}
5、handle 方法
handle 是执行任务完成时对结果的处理。 handle 方法和 thenApply 方法处理方式基本一样。不同的是 handle 是在任务完成后再执行,还可以处理异常的任务。thenApply 只可以执行正常的任务,任务出现异常则不执行 thenApply 方法。