感觉好久没有更新点东西了,自己都看不下去了啊……
前言
CompletableFuture 是 java8 提供的功能,java8至今已经挺久了,所以也不能算新东西,不过之前android的开发不太用到java8的特性,就连stream也用的是rxjava。
Future
在理解CompletableFuture,先理解Future还是非常重要的。因为CompletableFuture算是Future的增强版。 Future用于表示一个带返回值的异步计算过程。内部方法包括获取返回值,cancel任务,查看任务是否完成等。 Future有几个继承
- RunnableFuture 同时继承了Runnable和 Future的一个接口。最常用的FutureTask就是这个接口的实现类。ExecutorThreadPool调用submit方法就会创建一个FutureTask对象的返回。
- ScheduledFuture 继承了Future 和 Delayed 接口的一个接口,用于表示一个带delay效果的Future。然后RunnableScheduledFuture 进一步继承了ScheduledFuture 和 RunnableFuture,实际上就表示一个带有delay和周期运行功能的 RunnableFuture。他的最终实现类就是ScheduledFutureTask. 通过 ScheduledThreadPoolExecutor 线程池,调用schedule方法,实际返回的就是一个 ScheduledFutureTask。
Future还有几种继承类型,这个就和每一个知识点绑定来说,比如CompletableFuture,实际上也是Future的继承者。
CompletableFuture
实际上,CompletableFuture 的核心思想是函数式编程,这在java8中的流式机制stream中也有体现。在以前android开发中,承担起函数式开发重任的基础库是rxjava,不过在服务端开发中这个库并不是很常用,直接使用java8的特性就能实现大部分流操作。
CompletionStage
CompletionStage 类是CompletableFuture任务链的中间类,表示一个阶段状态,CompletableFuture本身就继承了这个接口,实际使用中我们很少直接用到这个类。不过CompletableFuture的流式功能就是通过这个类定义的,比如thenAccept等这些方法。
runAsync 和 supplyAsync方法
CompletableFuture 提供了四个静态方法来创建一个异步操作。
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可以支持返回值。
//无返回值
public static void runAsync() throws Exception {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
System.out.println("run end ...");
});
future.get();
}
//有返回值
public static void supplyAsync() throws Exception {
CompletableFuture<Long> future = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
System.out.println("run end ...");
return System.currentTimeMillis();
});
long time = future.get();
System.out.println("time = "+time);
}
流式方法
在开启一个CompleteFuture之后,后续就可以使用流式方法了,比如thenAccept表示消费处理结果。
public static void thenAccept() throws Exception{
CompletableFuture<Void> future = CompletableFuture.supplyAsync(new Supplier<Integer>() {
@Override
public Integer get() {
return new Random().nextInt(10);
}
}).thenAccept(integer -> {
System.out.println(integer);
});
future.get();
}
thenAccept消费了前一步返回的结果。顺带一提,还有一个thenAcceptAsync.
- thenAccept:是执行当前任务的线程执行继续执行 thenAccept 的任务。
- thenAcceptAsync:是执行把 thenAcceptAsync 这个任务继续提交给线程池来进行执行。
流式还有不少方法,不过没必要穷举说明,需要用到的时候查一下就好了。
参考
https://www.jianshu.com/p/6bac52527ca4
来源:oschina
链接:https://my.oschina.net/u/2398062/blog/3068946