繁体   English   中英

组成Java CompletableFutures时使用哪个执行程序?

[英]Which executor is used when composing Java CompletableFutures?

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

这是一个例子:

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

我的应用程序的其余部分将构成这些未来,并对结果做一些其他事情。 当这些其他函数提供给thenAcceptthenComposewhenComplete等时,我不希望它们在存储库的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的线程执行,也可以由完成方法的任何其他调用者执行。

附带问题:为什么在这里那里? 在哪种情况下,存在另一个无法完成当前将来的完成方法的调用者?

主要问题:如果我希望所有println都由与存储库使用的Executor不同的Executor ,我需要哪种方法进行异步并手动提供执行器?

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

替代问题:哪个线程完成了thenCompose返回的future?

我的猜测是,它将完成函数自变量返回的将来的线程。 换句话说,我还需要将whenComplete更改为whenCompleteAsync

也许我使事情复杂化了,但是这感觉可能很棘手。 我需要非常注意所有这些期货的来源。 同样从设计的角度来看,如果我返回未来,如何防止调用者使用我的执行器? 感觉好像破坏了封装。 我知道Scala中的所有转换函数都采用一个隐式的ExecutionContext ,似乎可以解决所有这些问题。

补充问题:如果您将中间CompletionStage分配给变量并在其上调用方法,则它将在同一线程上执行。

主要问题:仅第一个,因此将thenAccept更改为thenAcceptAsync -以下所有这些将在用于接受的线程上执行其步骤。

替代问题:从thenCompose完成未来的线程与用于撰写的线程相同。

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

在您当前的设置中,步骤将像这样执行:

Thread-1: delete, accept, compose, complete

通过第一个接受异步,它变为:

Thread-1: delete
Thread-2: accept, compose, complete

关于最后一个问题,如果调用者添加其他步骤,它们将使用相同的线程-我认为除了不返回CompletableFuture ,除了正常的Future之外,您还可以做很多事情。

仅仅根据我在使用它时的经验观察,执行这些非异步方法的线程将取决于首先发生的是什么, thenCompose取决于其自身或Future的任务。

如果thenCompose首先完成(在您的情况下,几乎可以确定),则该方法将在执行Future任务的同一线程上运行。

如果Future后面的任务首先完成,则该方法将立即在调用线程上运行(即根本没有执行程序)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM