【问题标题】:completablefuture runasync in foreach loopforeach循环中的completablefuture runasync
【发布时间】:2019-04-04 06:15:50
【问题描述】:

我已经在 foreach 循环中定义了 completablefuture runasync() 任务。

我需要在 nosql db 中插入记录,并且需要更新与 sql db 中“已处理”相同的插入记录(将数据从 sqldb DB2 迁移到 nosql mongodb)。

为了实现这一点,我在 runasyn() 中定义了 mongo 插入过程,并在 thenAccept() 中定义了在 db2 中处理的数据更新函数(检查代码 sn-p)

所以问题是在 mongo 中的每个记录插入之后,我将插入的记录保留在列表中并尝试一次更新 db2 中的整个列表,但它的行为并非如此,对于 mongo 中的每次插入,它都会为每条记录命中 db2更新,但在处理数千条记录时这是不可行的方法。我的期望是首先获得 mongo 插入记录列表,然后一次性将这些记录列表更新为 db2 中的“已处理”。这种方法有可能吗? (我知道在 foreach 循环中定义了 mongo 插入和 db2 更新,但我希望 mongo 应该完成所有条目的插入,然后需要一次性更新整个 mongo 插入列表的 db2) 或者,如果我至少能够从 mongoProcess 返回插入记录的列表。

代码sn-p:

unprocessedList.foreach(entry-> {
Completablefuture <Void> cf= Completablefuture.runAsync(() -> {
mongoHelper.processInMongo(entry, getObj(entry)) } , executor). thenAccept ( 
updateInDb2 ( entryList)) });

【问题讨论】:

  • 你的问题是......非常混乱且难以阅读,你能试着清理一下吗?您可能想请会说英语的人来帮助您表达您的实际问题
  • 所以你在 mongodb 中分别插入每条记录。你为什么不一批做呢?那么你根本不需要使用 Completablefuture。
  • @AlexeiKaigorodov 我们正在验证每条记录中的指标,基于我们在 mongo 中更新或插入数据,因此此处无法批量插入。

标签: multithreading concurrency java-8 completable-future


【解决方案1】:

如果我对您的理解正确,您希望完成所有插入,然后再进行一次更新。 您可以更改您的代码以使用 Promises(我自己对 Java 不太熟悉)所以这里有一个“基本”解决方案来解决您的问题。

请注意,您应该使用 atomicInterger 作为计数器变量,因为 ++ 不是原子的,否则 100% 的时间都不会工作

function x (count, expected) {
 if(count == expected) {
    updateInDb2 ( entryList)) 
   }
}

counter = 0:

unprocessedList.foreach(entry-> {
    Completablefuture <Void> cf= Completablefuture.runAsync(() -> {
    mongoHelper.processInMongo(entry, getObj(entry)) } , executor).thenAccept(
   counter++;
   x(counter, unprocessedList.length);
 });

正如我所说,我对 java 承诺不太熟悉,但更好的解决方案是:

await promise = 插入所有 mongo 文档 承诺兑现然后更新列表

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-11
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 2021-05-28
    • 1970-01-01
    • 2016-09-26
    相关资源
    最近更新 更多