异步计算
-
所谓异步调用其实就是实现一个可无需等待被调用函数的返回值而让操作继续运行的方法。在 Java 语言中,简单的讲就是另启一个线程来完成调用中的部分计算,使调用继续运行或返回,而不需要等待计算结果。但调用者仍需要取线程的计算结果。
-
JDK5新增了Future接口,用于描述一个异步计算的结果。虽然 Future 以及相关使用方法提供了异步执行任务的能力,但是对于结果的获取却是很不方便,只能通过阻塞或者轮询的方式得到任务的结果。阻塞的方式显然和我们的异步编程的初衷相违背,轮询的方式又会耗费无谓的 CPU 资源,而且也不能及时地得到计算结果。
Future 接口的局限性
- Future接口可以构建异步应用,但依然有其局限性。它很难直接表述多个Future 结果之间的依赖性。实际开发中,我们经常需要达成以下目的:
- 将多个异步计算的结果合并成一个
- 等待Future集合中的所有任务都完成
- Future完成事件(即,任务完成以后触发执行动作)
CompletionStage
- CompletionStage代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段
- 一个阶段的计算执行可以是一个Function,Consumer或者Runnable。比如:stage.thenApply(x -> square(x)).thenAccept(x -> System.out.print(x)).thenRun(() -> System.out.println())
- 一个阶段的执行可能是被单个阶段的完成触发,也可能是由多个阶段一起触发
CompletableFuture
- 在Java8中,CompletableFuture提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性,并且提供了函数式编程的能力,可以通过回调的方式处理计算结果,也提供了转换和组合 CompletableFuture 的方法。
- 它可能代表一个明确完成的Future,也有可能代表一个完成阶段( CompletionStage ),它支持在计算完成以后触发一些函数或执行某些动作。
- 它实现了Future和CompletionStage接口
public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
......
}
实例代码
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) throws Exception {
//案例1, 没有返回值
/*
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
System.out.println("没有返回,update mysql ok");
});
voidCompletableFuture.get();
*/
/*案例2,有返回值*/
CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(() -> {
System.out.println("有返回,insert mysql ok");
//模拟异常情况
int i= 10/0;
//正常返回
return 1024;
});
Integer result= completableFuture2.whenComplete((x,y)->{
//x 为返回值,y为异常信息
System.out.println(String.format("whenComplete:x: %s,y:%s", x, y));
}).exceptionally(f->{
System.out.println(String.format("exceptionally :%s", f.getMessage()));
return 404;
}).get();
System.out.println(String.format("get result:%s",result));
//System.out.println( );
//同步,异步,异步回调
//同步
// CompletableFuture<Void> completableFuture1 = CompletableFuture.runAsync(()->{
// System.out.println(Thread.currentThread().getName()+"\t completableFuture1");
// });
// completableFuture1.get();
//异步回调
/*CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread().getName()+"\t completableFuture2");
int i = 10/0;
return 1024;
});
completableFuture2.whenComplete((t,u)->{
System.out.println("-------t="+t);
System.out.println("-------u="+u);
}).exceptionally(f->{
System.out.println("-----exception:"+f.getMessage());
return 444;
}).get();*/
}
}
参考 : 尚硅谷JUC周阳版 https://www.cnblogs.com/cjsblog/p/9267163.html