java - 使用 CompletableFuture 回调是否有性能优势?

标签 java completable-future

CompletableFuture 允许为异步调用提供回调。您可以创建一长串回调,其中每个异步调用将在完成时触发下一个回调。这被认为是编写异步代码的更好方法,而不是使用 Future,在 Future 中,您必须阻塞线程才能在触发下一个计算之前获取第一个计算的结果。

我可以理解 Completable Futures 中的回调链可以提供更具可读性的代码这一论点,但我想知道这种方法是否也有性能优势,或者它只是一个语法糖?

例如,考虑以下代码:

    ExecutorService exec = Executors.newSingleThreadExecutor();
    CompletableFuture.supplyAsync(this::findAccountNumber, exec)
                     .thenApply(this::calculateBalance)
                     .thenApply(this::notifyBalance)
                     .thenAccept((i)->notifyByEmail())
                     .join();

在此代码中,在 findAccountNumber() 完成之前,calculateBalance() 无法启动,因此基本上 calculateBalance()findAccountNumber() 上被阻止,对于回调链中的下一个方法,依此类推。它比以下内容如何更好(性能方面):

    ExecutorService exec = Executors.newSingleThreadExecutor();
    Future<Integer> accountNumberFuture = exec.submit(findAccountNumberCallable);
    Integer accountNumber = accountNumberFuture.get();
    Future<String> calculateBalanceFuture = exec.submit(calculateBalanceCallable(accountNumber);
    ....
    ....

最佳答案

在大多数情况下,您不会注意到差异,但如果您希望能够有大量并发异步调用等待某些内容,则需要使用 CompletableFuture

原因是,如果您只是在常规 Future 上调用 get()Thread 以及与其关联的所有资源都会被阻塞,直到调用返回。如果您有很多调用,您的线程池可能会耗尽,或者如果您使用CachedThreadPool,您可能会导致创建大量线程。

使用CompletableFuture,对象存储在堆上,该对象表示应用程序下一步应该拾取的位置,而不是使用调用堆栈。构建 API 的人通过 here 进行了讨论。 .

关于java - 使用 CompletableFuture 回调是否有性能优势?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57547836/

相关文章:

java - CompletableFuture 的问题 - 不等待所有 URL 被调用

java - 优先级队列并集、交集、差异编译但不返回输出

java - 对于(房间 r : ArrayList<Room>) returns empty Room

Java gRPC 服务器用于长生命周期流的有效实现

java - 如何捕获 CompletableFuture 的 whenCompleteAsync 调用中抛出的 RejectedExecutionException?

Spring Controller 建议无法正确处理 CompletableFuture 异常完成

java - System.gc 将在 android(Andengine) 中工作

java - 编写 SQL 查询以返回 2 个 sqlite 表中的所有字段(Android 应用程序)

java - CompletableFuture 对象数组的空检查

java - "Double"与 CompletableFuture 的组合