首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >lambda预先创建了比预期更少的parallelStream数据

lambda预先创建了比预期更少的parallelStream数据
EN

Stack Overflow用户
提问于 2019-01-29 10:30:37
回答 1查看 1.7K关注 0票数 5

为了提高现有应用程序的性能,我正在尝试实现数组列表的lambda并行流。

到目前为止,在没有并行流的情况下,foreach迭代创建了写入数据库的预期数据量。

但是,当切换到parallelStream时,总是将较少的行写入数据库。假设从预期的10.000行开始,大约有7000行,但是结果在这里有所不同。

知道我在这里遗漏了什么,数据竞争条件,还是必须使用锁和同步?

代码基本上是这样做的:

代码语言:javascript
复制
// Create Persons from an arraylist of data

arrayList.parallelStream()
          .filter(d -> d.personShouldBeCreated())
          .forEach(d -> {

   // Create a Person
   // Fill it's properties
   // Update object, what writes it into a DB

  }
);

到目前为止我尝试过的事物,

在一个新的列表中收集结果。

代码语言:javascript
复制
collect(Collectors.toList())

然后,...and迭代新列表并执行第一个代码片段中描述的逻辑。新的“收集”的ArrayList的大小与预期的结果相匹配,但最终数据库中创建的数据仍然较少。

Update/Solution:

基于我在代码中标记的关于非线程安全部件的答案(以及注释中的提示),我按照以下方式实现了它,最后给出了预期的数据量。性能已经提高,现在只需要以前的1/3的实现。

代码语言:javascript
复制
StringBuffer sb = new StringBuffer();
arrayList()
  .parallelStream()
  .filter(d-> d.toBeCreated())
  .forEach(d ->
    sb.append(
            // Build an application specific XML for inserting or importing data
    )
  );

应用程序特定的部分是一个基于XML的数据导入api,但我认为这可以在普通的SQL插入中完成。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-29 18:44:50

最有可能的情况是,lambda中的代码不是线程安全的,因为代码使用共享的非并发数据结构或它们的操作需要锁定。

我怀疑批/批量插入会比并行版本更快,而并行版本可能会以庞大的短时间连接结束,这些连接将在它们之间竞争锁定您正在插入的表。

也许您可以在并行地组合大容量插入文件内容方面获得一些好处,但这将取决于如何通过数据库API实现大容量插入。它需要先转储到文本文件中吗?在这种情况下,您的并行流可以并行地组成文本的不同行,并最终将它们连接到文本文件中,加载到DB中。也许它不是文本文件,而是允许您在内存中使用语句对象的集合/列表,在这种情况下,并行流可以并行地创建这些对象,并将它们收集到最终的集合/列表中,然后批量插入到DB中。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54418983

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档