当前位置: 首页 > 知识库问答 >
问题:

编写Java CompletableFutures时使用哪个执行器?

宁弘亮
2023-03-14

我在某个存储库类上有一个方法,它返回completablefuture。完成这些期货的代码使用一个第三方库来阻止。我打算有一个单独的有界executor,这个存储库类将使用它来进行这些阻塞调用。

这里有一个例子:

public class PersonRepository {
    private Executor executor = ...
    public CompletableFuture<Void> create(Person person) {...}
    public CompletableFuture<Boolean> delete(Person person) {...}
}

我的应用程序的其余部分将组成这些期货,并用结果做一些其他的事情。当提供给thenacceptthencomposewhencomplete等的其他html" target="_blank">函数时,我不希望它们在存储库的executor上运行。

另一个例子:

public CompletableFuture<?> replacePerson(Person person) {
    final PersonRepository repo = getPersonRepository();
    return repo.delete(person)
        .thenAccept(existed -> {
            if (existed) System.out.println("Person deleted"));
            else System.out.println("Person did not exist"));
        })
        .thenCompose(unused -> {
            System.out.println("Creating person");
            return repo.create(person);
        })
        .whenComplete((unused, ex) -> {
            if (ex != null) System.out.println("Creating person");
            repo.close();
        });
}

JavaDoc声明:

为非异步方法的从属完成提供的操作可以由完成当前CompletableFuture的线程执行,也可以由completion方法的任何其他调用方执行。

显然,thenAccept需要更改为thenAcceptAsync,但我不确定这一点。

备选问题:哪个线程完成从thencompose返回的future?

我的猜测是,无论线程完成了什么,它都将是函数参数返回的未来。换句话说,我还需要将whencomplete更改为whencompleteasync

也许我已经把事情复杂化了,但这感觉它可能会变得相当棘手。我需要非常注意这些期货是从哪里来的。同样从设计的角度来看,如果我返回一个未来,我如何阻止调用方使用我的执行器?感觉就像是破坏了封装。我知道Scala中的所有转换函数都采用一个隐式的executionContext,它似乎可以解决所有这些问题。

共有1个答案

邢献
2023-03-14

附带问题:如果您将中间的completionstage赋给一个变量并在其上调用一个方法,那么它将在同一线程上执行。

主要问题:只有第一个,所以将thenAccept更改为thenAcceptAsync--以下所有的都将在用于接受的线程上执行它们的步骤。

备选问题:从thencompose完成未来的线程与用于compose的线程相同。

您应该将CompletionStages视为在同一线程上快速连续执行的步骤(只需按顺序应用函数),除非您特别希望使用Async在不同的线程上执行该步骤。接下来的所有步骤都是在新线程上完成的。

在当前的设置中,这些步骤将按如下方式执行:

Thread-1: delete, accept, compose, complete

对于第一个accept异步,它变为:

Thread-1: delete
Thread-2: accept, compose, complete
 类似资料:
  • 假设我们有两个执行人,1和2。 我们可以配置在执行时使用哪个执行器 但哪个线程执行器使用CompletableFuture静态方法allOf? 谢啦!

  • 换句话说,你是可以平等地将它们视为存储空间,还是应该坚持将它们用于特定目的?

  • 我正在使用脚本模式(一种groovy脚本)与Katalon Studio创建一个测试用例。我需要那个groovy脚本来执行将位于Katalon项目文件夹中。 出于测试目的,我创建了一个. jar,它创建了一个名为"the-file-name"的文件,并在控制台中打印一条消息。 我找到了在Groovy中执行命令的方法: 这会在Katalon控制台中打印git的版本。所以我猜放上“java-jar t

  • 在没有任何Java RMI经验的情况下,我有一个天真的问题,但在搜索互联网后仍然不确定答案。 问题: 对我来说,有两种情况: 场景1:从本地启动一个Java程序,在执行过程中,它从存储在远程机器上的类调用一个方法,然后该方法的类将下载到本地机器上,并继续执行。 场景2:从本地启动Java程序,在执行过程中,它从存储在远程机器上的类调用一个方法,然后该方法将在远程机器上执行,结果将发送回本地机器。(

  • 最近我安装了Composer,因为它是安装Yii框架的首选方式,但我似乎无法使用它,我不知道为什么。 这是使用composer命令时发生的一个示例:C:\wamp\www

  • 问题内容: 因此,我正在尝试编写一个将可执行的.sh文件,这是我目前正在编写的方式: 这样就可以写文件了,但是它不是可执行文件。当我编写可执行文件时,是否可以更改其状态? 编辑:为了进一步说明,我试图使其在默认情况下执行,例如,如果双击生成的文件,它将自动执行。 问题答案: 您需要对其进行chmod修改,并且可能可以通过执行如下系统命令来实现: 实际上,您所需要做的只是解散如下所示的内容: 但是,