当前位置: 首页 > 知识库问答 >
问题:

用Java将[chained]CompletableFutures写入CSV

酆恩
2023-03-14

我有一个hashmap >> 将一个项目映射到它的属性,例如{“pizza”->{“calories”->“120”,“fat”->“12”}},其中属性是从不同的数据源检索的。

例如,我们从数据库中获得“fat”属性,而从Solr中获得“calories”属性。

当我最初从DB检索“fat”时,我使用supplyAsync以避免阻塞主线程,如下所示:

  public CompletableFuture<HashMap<String, String>> getFat(String name, boolean) {
    return CompletableFuture.supplyAsync(new Supplier<HashMap<String, String>>() {
      @Override
      public HashMap<String, String> get() {
        HashMap<String, String> attributes = new HashMap<>();
        
        ... do work ...
      
        attributes.put(name, attributes);
        return attributes;
      }
   })
 }

然后通过对Solr的异步调用将其链接起来,这样我最终将有一个异步Hashmap将项映射到它们的属性,即Hashmap >itemstoattributesmapping; (因此我循环遍历Hashmap的键,并用新属性更新值,使用thenapply访问旧属性)。

最后,我将数据映射到csv,这就是问题所在:

       File file = new File(home + "/Downloads/rmsSkuValidationResults.csv");

       try{
          FileWriter outputfile = new FileWriter(file);
          CSVWriter writer = new CSVWriter(outputfile);

            for(String itemKey : itemsToAttributesMapping.keySet()) {
                itemsToAttributesMapping.get(itemKey).thenAccept(attributes -> {

                String[] row = { attributes.get("calories"),
                            attributes.get("fat")
                        
                        ... more attributes ...

                        };
                writer.writeNext(row);
                });
            }

         writer.close();
      }
      catch(Exception e){
        e.printStackTrace();
      }

实际上,打印到CSV文件可以很好地处理800-1100个项目,但在此之后就会停止写入,程序也会终止。

我尝试了对上述内容的修改,包括使用get代替thenaccept,或者在thenaccept后面添加join导致程序挂起(异步计算很快,不应该挂起)。

我还尝试存储我运行的thenaccepts的结果,然后对其调用allof,但这会导致奇怪的行为,在几百个项目之后,Solr的属性就不再显示了。数据库中的属性确实会为每个项显示出来,这使我认为第一个SupplyAsync总是工作的,但是后续的ThenApply将属性添加到HashMap >ItemstoAttributesMapping; 提供的SupplyAsNC中的ThenApply停止工作。

如果你能洞悉问题所在,我将不胜感激。也许我对CompletableFuture的理解是不正确的,尤其是在链接和解决Futures上?这可能是超时问题,或者线程丢失了?我所阐述的最后一种方法暗示问题可能是thenapplys?

共有1个答案

李意致
2023-03-14

下面是上面的代码正在做什么的粗略说明:

get(itemKey1) then at some unspecified time in the future writeNext(attr1)
get(itemKey2) then at some unspecified time in the future writeNext(attr2)
get(itemKey3) then at some unspecified time in the future writeNext(attr3)
get(itemKey4) then at some unspecified time in the future writeNext(attr4)
get(itemKey5) then at some unspecified time in the future writeNext(attr5)
get(itemKey6) then at some unspecified time in the future writeNext(attr6)
get(itemKey7) then at some unspecified time in the future writeNext(attr7)
attr1 finally delivered; writeNext(attr1)
get(itemKey8) then at some unspecified time in the future writeNext(attr8)
attr2 finally delivered; writeNext(attr2)
attr3 finally delivered; writeNext(attr3)
get(itemKey9) then at some unspecified time in the future writeNext(attr9)
no more items; writer.close()
attr4 finally delivered; oops, writer closed
attr5 finally delivered; oops, writer closed
attr6 finally delivered; oops, writer closed
attr7 finally delivered; oops, writer closed
attr8 finally delivered; oops, writer closed
attr9 finally delivered; oops, writer closed

您提到您尝试了.get().join()。这基本上会使程序同步,但这是一个很好的调试步骤。它会将执行更改为:

get(itemKey1) then at some unspecified time in the future writeNext(attr1)
attr1 finally delivered; writeNext(attr1)
get(itemKey2) then at some unspecified time in the future writeNext(attr2)
attr2 finally delivered; writeNext(attr2)
get(itemKey3) then at some unspecified time in the future writeNext(attr3)
attr3 finally delivered; writeNext(attr3)
...
...
...
get(itemKey9) then at some unspecified time in the future writeNext(attr9)
attr9 finally delivered; writeNext(attr9)
no more items; writer.close()

这本该奏效的。将输出添加到每个阶段(您没有显示的thenapply,以及thenaccept)会显示什么?真的像你说的那么快吗?

请显示更多代码。尤其是链接部分,如果你认为这是问题所在的话。

 类似资料:
  • 我在某个存储库类上有一个方法,它返回。完成这些期货的代码使用一个第三方库来阻止。我打算有一个单独的有界,这个存储库类将使用它来进行这些阻塞调用。 这里有一个例子: 我的应用程序的其余部分将组成这些期货,并用结果做一些其他的事情。当提供给、、等的其他函数时,我不希望它们在存储库的上运行。 另一个例子: JavaDoc声明: 为非异步方法的从属完成提供的操作可以由完成当前CompletableFutu

  • 我是Java新手。我一直在从事一个使用Maven和Java1.7的项目。在我的项目中,我有一个HashMap。我想将这个HashMap输出到JSON。目前推荐的方法是什么? 当我在谷歌上搜索时,我有很多选择(比如杰克逊)。然而,我不确定我应该用什么。另外,我想使用一个可以通过Maven访问的图书馆。 非常感谢。

  • 我正在用s设计异步调用。这是一个批处理调用,在这里我需要同时处理几个实体。在呼叫结束时,我必须收集关于每一个项目的处理状态的信息。 作为输入,我有这些实体的ID数组。这是一个复杂的实体,为了将一个实体编译成一个对象,我必须发出几个DAO调用。每个DAO方法都返回。 我将那些DAO调用链接起来,因为如果其中一个部分不存在,我将无法构造一个完整的对象。下面是我的代码段的样子: 问题是,由于链接的关系,

  • 问题内容: 在这里很难说出要问什么。这个问题是模棱两可,含糊,不完整,过于宽泛或夸张的,不能以目前的形式合理地回答。如需帮助澄清此问题以便可以重新打开, 请访问帮助中心。 7年前关闭。 如何在Java中将字节数组转换为File? 问题答案: 一个 文件对象 不包含文件的内容。它仅是硬盘(或其他存储介质,如SSD,USB驱动器,网络共享)上文件的指针。因此,我认为您想要将其写入硬盘。 您必须使用Ja

  • 问题内容: 嗨,我正在尝试将字符串写入文本文件,但是有一个小问题。我在该站点上其他问题的帮助下完成了代码,但是当我尝试向文本文件中添加字符串时,它将擦除该文本文件中的所有内容并写入输入。但我希望它转到下一行并编写。我无法解决。我将不胜感激任何帮助。谢谢.. 问题答案: (未试用)您是否尝试过JavaDoc中提到的方法?

  • 请帮我解决这个问题。 提前谢谢你。