JDK8引入了大量的新特性和增强如Lambda表达式,Streams,CompletableFuture等。本篇文章结合代码案例讲解下CompletableFuture常见用法。
什么是CompletableFuture?
在Java中CompletableFuture用于异步编程,异步编程是编写非阻塞的代码,运行的任务在一个单独的线程,与主线程隔离,并且会通知主线程它的进度,成功或者失败。
在这种方式中,主线程不会被阻塞,不需要一直等到子线程完成。主线程可以并行的执行其他任务。
使用这种并行方式,可以极大的提高程序的性能。
CompletableFuture相对于传统的Future的优势
1. 可以手动完成调用future.complete()
2.多个 Future 可以串联在一起组成链式调用 执行一个长时间运行的计算任务,并且当计算任务完成的时候,你需要把它的计算结果发送给另外一个长时间运行的计算任务等等
3.Future可以在非阻塞的情况下执行进一步的操作,利用thenApply(),thenAccept() 和 thenRun() API 可以实现。
4.可以组合多个Future结果,使用API:allof(),anyof(),thenCombine(),thenCompose()
5.增加了异常处理API,没有任务的异常处理结构有很多的限制。
1.get() 阻塞获得CompletableFuture的结果;get()
方法会一直阻塞直到 Future 完成。因此,以上的调用将被永远阻塞,因为该Future一直不会完成。
2.runAsync()用于运行异步计算,通常异步运行一个后台任务不需要该任务的返回结果。(注意:这里的Runnable对象采用的是Lambda表达式)
//runAsync() 运行异步计算 异步运行一个后台任务不需要该任务的返回结果
@Test
public void test01() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture = new CompletableFuture<String>();
completableFuture.complete("finished future");
completableFuture.get(); // get 方法会阻塞直到future完成
System.out.println("completableFuture finished");
//Using Lambda expression
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("在独立的子线程运行,非主线程");
});
future.get();
}
3.supplyAsync()用于异步运行并返回结果。当运行异步线程你需要依赖它的返回结果时,就使用该方法。
@Test
public void test02() throws ExecutionException, InterruptedException {
CompletableFutur