gpt4 book ai didi

java - 解决并发问题的最佳方法

转载 作者:行者123 更新时间:2023-11-30 02:49:08 26 4
gpt4 key购买 nike

我正在尝试填充一个Person。许多 setter 方法需要一些时间来填充,因为数据是由数据库调用提供的,可能需要一些时间(超过 10 秒)才能返回。

我正在寻找在将我的 Person 返回到调用方法之前异步填充我的更改器(mutator)的最佳方法。

这是一个例子:

Person p = service.getPersonById(id);
// populate from DMV DB
p.setTickets(dmvService.getTicketsById(id)); // takes 15 seconds to return data
p.setAccidentRecord(dmvService.getAccidentsById(id)); // takes 10 seconds.
...
...

return p;

我希望能够异步运行我的方法(setTicketssetAccidentRecord 等),以将加载时间从超过 25 秒减少到大约 15 秒。

最佳答案

CompletableFuture Java 8 中引入的 只是门票。它是一个单子(monad)、可链接的类,可以轻松管理线程外计算。

future 表示将在未来某个时间完成并产生结果的计算。它可能已经完成,或者在某些后台线程中可能需要一段时间。 CompletableFuture 建立在这个核心概念的基础上,让您可以将各种附加转换和处理程序附加到现有的 future。

Person p = service.getPersonById(id);

CompletableFuture.allOf(
CompletableFuture.supplyAsync(() -> dmvService.getTicketsById(id))
.thenAccept(p::setTickets),

CompletableFuture.supplyAsync(() -> dmvService.getAccidentsById(id))
.thenAccept(p::setAccidentRecord)
).join();

return p;

根据您的情况,您可以使用 supplyAsync在后台线程中运行 getTicketsByIdgetAccidentsById。由于您希望在这些方法返回时调用相应的 setter,因此您可以使用 thenAccept也就是说,“当该方法返回时,向此 setter 提供值”。

您有两个后台计算,并且在它们都完成之前您不想返回。将这两个 future 包装成一个更大的 future allOf带我们去那里。在两个内部 future 都完成之前,allOf future 本身不会完成。

最后,我们join allOf future,等待它完成后再继续。如果任何代码可能抛出异常,那么 join 将抛出该异常本身 - 尽管它会被包装在 CompletionException 中 - 因此您可以添加一个 try/catch如果你愿意的话就可以。

<小时/>

不幸的是,Java 首次尝试这个概念,Future,是一个功能不足、乏善可陈的类。他们用 CompletableFuture 得到了正确的结果,但是 Future 窃取了理想的名称。

关于java - 解决并发问题的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39261208/

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