前言
Future的问题
写多线程程序的时候,可以使用Future从一个异步线程中拿到结果,但是如果使用过程中会发现一些问题:
-
如果想要对Future的结果做进一步的操作,需要阻塞当前线程
-
多个Future不能被链式的执行,每个Future的结果都是独立的,期望对一个Future的结果做另外一件异步的事情;
-
没有异常处理策略,如果Future执行失败了,需要手动捕捉
CompletableFuture应运而生
为了解决Future问题,JDK在1.8的时候给我们提供了一个好用的工具类CompletableFuture;
它实现了Future和CompletionStage接口,针对Future的不足之处给出了相应的处理方式。
- 在异步线程执行结束后可以自动回调我们新的处理逻辑,无需阻塞
- 可以对多个异步任务进行编排,组合或者排序
- 异常处理
CompletableFuture的核心思想是将每个异步任务都可以看做一个步骤(CompletionStage),然后其他的异步任务可以根据这个步骤做一些想做的事情。
CompletionStage定义了许多步骤处理的方法,功能非常强大,这里就只列一下日常中常用到的一些方法供大家参考。
使用方式
基本使用-提交异步任务
简单的使用方式
异步执行,无需结果:
// 可以执行Executors异步执行,如果不指定,默认使用ForkJoinPool
CompletableFuture.runAsync(() -> System.out.println("Hello CompletableFuture!"));
复制代码
异步执行,同时返回结果:
// 同样可以指定线程池
CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> "Hello CompletableFuture!");
System.out.println(stringCompletableFuture.get());
复制代码
处理上个异步任务结果
-
thenRun: 不需要上一步的结果,直接直接新的操作
-
thenAccept:获取上一步异步处理的内容,进行新的操作
-
thenApply: 获取上一步的内容,然后产生新的内容
所有加上Async后缀的,代表新的处理操作仍然是异步的。Async的操作都可以指定Executors进行处理