日常开发中,我们经常会用到多线程去进行异步任务处理,通过继承Thread类或者实现Runnable接口开启的异步任务,我们要获取异步线程执行结果不是很方便,在JDK1.5已经提供了Future和Callable的实现,我们可以获取异步任务的执行结果了。
Future小demo下面通过Futrue的小demo来简单演示下Futrue的用法
@Test
public void testFuture() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
System.out.println("开始异步任务");
Future future = executorService.submit(() -> {
System.out.println("开启异步线程,模拟异步任务" + Thread.currentThread().getName());
Thread.sleep(3000);
return "爱琴孩";
});
System.out.println("开始获取异步任务结果,当前线程阻塞" + Thread.currentThread().getName());
String name = future.get();
System.out.println("异步任务结果:" + name);
}
执行结果如下
开始异步任务 开始获取异步任务结果,当前线程阻塞main 开启异步线程,模拟异步任务pool-1-thread-1 异步任务结果:爱琴孩
上面的future.get()方法会阻塞当前线程,直到异步线程执行ok之后才会重新执行主线程的后续逻辑。或者通过轮询调用future.isDone()来判断异步任务是否执行结束。轮询的方式会耗费无谓的CPU资源,而且也不能及时地得到计算结果,Future没有提供异步回调功能。同时对于多个异步任务的执行结果组合,Future也不是很友好,所以在jdk1.8引入的CompletableFuture。扩展了Future和CompletionStage,是一个可以在任务完成阶段触发一些操作的Future。简单的来讲就是可以实现异步回调,同时支持任务的流式处理和多个任务的组合处理功能。
初识CompletableFutureCompletableFuture的小demo
@Test
public void testCompletableFuture() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
System.out.println("开启异步");
return "爱琴孩";
}, executorService);
String name = future.get();
System.out.println("获取异步任务结果"+name);
}
执行结果如下
开启异步 获取异步任务结果爱琴孩
有些小伙伴看到这里不淡定了,CompletableFuture中的get()和Future中的get()有啥区别,不都是一样阻塞当前线程么?是的,get()确实没差,但是CompletableFuture还提供了很多很有用的方法,否则CompletableFuture的意义何在,首先看下CompletableFuture类图
CompletableFuture实现了Future和CompletionStage接口,它提供了很多方法进行异步任务的流式处理和多任务的编排组合功能
上面截图中的方法只是CompletableFuture的一部分方法,后面会和大家一起深入学习CompletableFuture在各种场景下的使用。



