Java 9中CompletableFuture和Future之间的区别是什么?

1. 什么是Future?

在Java中,当一个方法需要一定的时间来执行,而我们不想等待它完成,同时又需要它的结果时,就可以使用Future。Future是一个接口,它表示一个异步计算的结果。我们可以使用它来检查计算是否完成,等待计算的完成,并获取计算的结果。

使用Future的示例:

ExecutorService executor = Executors.newSingleThreadExecutor();

Future futureResult = executor.submit(() -> {

// 执行一些耗时操作

return "result";

});

// 在这里进行其他操作

String result = futureResult.get(); // 阻塞直到异步操作完成,获取结果

上面的示例中,我们使用ExecutorService和submit方法提交了一个异步计算。submit方法返回了一个Future对象,我们可以使用它来获取计算的结果。

2. 什么是CompletableFuture?

CompletableFuture是Java 8中引入的类,它是Future的扩展,提供了对异步计算的支持。与Future不同的是,CompletableFuture具有更加强大和灵活的功能,并且可以链式调用,能够更加方便地处理异步计算结果。

CompletableFuture提供了丰富的API,可以实现异步计算和多个异步计算的组合和转换,同时还能处理异常和取消操作。使用CompletableFuture可以更加简洁和优雅地编写异步代码。

3. CompletableFuture和Future的区别

3.1 异步操作的启动方式

Future:Future的异步操作需要显式地提交到一个ExecutorService中执行,通常使用executor.submit()方法提交一个Callable或Runnable任务。

CompletableFuture:CompletableFuture支持两种异步操作的启动方式:

使用runAsync()或supplyAsync()方法创建一个异步计算任务,并且指定一个线程池来执行任务。

使用CompletableFuture.supplyAsync()或CompletableFuture.runAsync()方法创建一个新的CompletableFuture,并且使用前一个CompletableFuture的计算结果作为参数。

3.2 得到异步计算结果的方式

Future:获取Future的计算结果可以调用Future.get()方法,如果异步计算还没有完成,get()方法会阻塞当前线程,直到异步计算完成。

CompletableFuture:CompletableFuture提供了多个方法获取异步计算结果:

使用get()方法获取计算结果,如果异步计算还没有完成,get()方法会阻塞当前线程。

使用join()方法获取计算结果,它的行为类似于get()方法,但是不会抛出checked异常。

使用whenComplete()、handle()和 exceptionally()方法处理异步计算的结果和异常。

使用thenApply()、thenAccept()和thenRun()方法组合多个异步计算任务。

3.3 处理异常的方式

Future:Future没有提供处理异步计算异常的方法,只有一个get()方法会抛出ExecutionException异常,它将计算过程中抛出的异常包装在其中。

CompletableFuture:CompletableFuture提供了多个方法处理异步计算中的异常,包括:handle()、whenComplete()和 exceptionally()方法。

3.4 链式调用的支持

Future:Future不支持链式调用,不能方便的处理多个异步计算任务的结果。

CompletableFuture:CompletableFuture支持链式调用,它的每个方法都返回一个新的CompletableFuture,可以跟其他方法进行链式调用。

4. 使用CompletableFuture

下面是一个使用CompletableFuture的示例,它展示了如何创建并发执行两个异步计算,并且在两个计算完成后使用它们的结果执行一个异步操作。

CompletableFuture future1 = CompletableFuture.supplyAsync(() -> {

// 异步计算

return 100;

});

CompletableFuture future2 = CompletableFuture.supplyAsync(() -> {

// 异步计算

return 200;

});

CompletableFuture future3 = future1.thenCombineAsync(future2, (result1, result2) -> {

// 组合异步计算的结果

return "result: " + (result1 + result2);

});

String result = future3.join(); // 等待异步操作完成,并获取结果

5. 总结

Future和CompletableFuture都是Java中用于处理异步计算的接口和类。Future提供了对异步计算的基本支持,可以用于检测异步计算的完成,并获取计算的结果。CompletableFuture作为Future的扩展,提供了更加强大和灵活的功能,并且可以链式调用,能够更加方便地处理异步计算结果。

当需要处理更复杂的异步计算场景时,建议使用CompletableFuture,它提供了更加方便和灵活的API,并且能够更好地处理异常和组合多个异步计算任务。

后端开发标签