foreach循环中的completablefuture runasync

时间:2019-04-04 06:15:50

标签: multithreading concurrency java-8 completable-future

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

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

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

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

代码段:

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

1 个答案:

答案 0 :(得分:0)

如果我正确理解您的信息,则只想完成所有插入操作,然后再进行一次更新。 您可以更改代码以使用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 promise,但是更好的解决方案是采用以下形式:

等待诺言=插入所有mongo文档 兑现承诺,然后更新列表