gpt4 book ai didi

java - 如果任务是相关的,为什么要使用 completableFuture

转载 作者:行者123 更新时间:2023-12-02 09:26:43 25 4
gpt4 key购买 nike

我在我的应用程序中非常有效地使用 ExecutorServices,它必须处理订单处理,现在订单生命周期有多个阶段,需要按顺序完成。而 2 个订单应彼此独立处理。

Sudo 代码如下所示:

ExecutorService service = Executors.newFixedThreadPool(100);
List<Future<Boolean>> orderStatus = new ArrayList<>();
for (int i = 0; i < 100 ; i++) {
Future<Boolean> status = service.submit(() -> {
ProcessOrder();
});
orderStatus.add(status);
}

public Boolean ProcessOrder(){
Order order = PollOrder();
order = EnrichOrder(order);
order = Payment(order);
order = confirmOrder(order);
return true;
}
另一方面,如果我使用 CompleteableFuture,我看到的唯一优点是使用通用的 forkjoin 池,其中代码看起来简单且可读性强,但由于任务以相同的顺序相互依赖,因此处理什么是当 get() 在任何情况下阻塞时,使用 CompleteableFuture 的实际优势。

for (int i = 0; i < 100 ; i++) {
CompletableFuture<Order> orderStatus= CompletableFuture.supplyAsync(()->pollOrder())
.thenApply(order -> enrichOrder(order))
.thenApply(order -> payment(order))
.thenApply(order -> confirmOrder(order));
}

最佳答案

我认为一个优点是更好地利用线程池。 ExecutorService 代码示例对每个操作使用相同的池。这些操作可以是 IO 密集型或计算密集型。在不同的池上运行这些操作将更好地利用系统资源。(*) 使用 CompletableFuture 的异步方法在不同的池上运行任务非常容易。

CompletableFuture.supplyAsync(()->comp1()) // start in common-pool
.thenApplyAsync(order -> io1(order),ioPool) // lets say this is IO operation
.thenApplyAsync(order -> comp2(order)) // switch back to common-pool
.thenApplyAsync(order -> io2(order),ioPool); // another io

在此示例中,当 comp1 任务完成时,io1 任务将在 IO 线程池中执行,公共(public)池线程在此期间可以服务其他任务。 io1任务结束后,comp2任务将被提交到common-pool。

不使用 CompletableFuture 也可以实现同样的效果,但代码会更复杂。 (就像将 comp2 任务作为参数传递给 io1 方法,最后从 io1 方法将其提交到公共(public)池中。)

此外,在编写异步代码时,我认为 completableFuture 管道应该使用另一个异步调用而不是 get 方法来完成。

(*) 假设这是在 8 核机器上运行的代码,向这个 100 个线程池提交 100 个计算任务不会比一次运行 8 个任务更好。

关于java - 如果任务是相关的,为什么要使用 completableFuture,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58292614/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com