有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java并行流调用parallel()方法的顺序

AtomicInteger recordNumber = new AtomicInteger();
Files.lines(inputFile.toPath(), StandardCharsets.UTF_8)
     .map(record -> new Record(recordNumber.incrementAndGet(), record)) 
     .parallel()           
     .filter(record -> doSomeOperation())
     .findFirst()

当我写这篇文章时,我假设线程将只在map调用中产生,因为parallel放在map之后。但文件中的一些行每次执行都会得到不同的记录编号

我阅读了官方的Java stream documentation和一些网站,以了解流是如何在引擎盖下工作的

有几个问题:

  • Java并行流基于SplitIterator工作,它由ArrayList、LinkedList等每个集合实现。当我们从这些集合构造并行流时,将使用相应的拆分迭代器拆分和迭代集合。这解释了为什么并行性发生在原始输入源(文件行)级别,而不是map(即Record pojo)的结果级别。我的理解正确吗

  • 在我的例子中,输入是一个文件IO流。将使用哪个拆分迭代器

  • 我们把parallel()放在管道的什么地方并不重要。原始输入源将始终被拆分,其余的中间操作将被应用

    在这种情况下,Java不应该允许用户将并行操作放在管道中的任何位置,除了原始源位置。因为,对于那些不知道java流在内部如何工作的人来说,这是一种错误的理解。我知道parallel()操作应该是为流对象类型定义的,所以它是这样工作的。但是,最好提供一些替代解决方案

  • 在上面的代码片段中,我试图向输入文件中的每条记录添加行号,因此应该对其进行排序。然而,我想并行地应用doSomeOperation(),因为它是一种重型逻辑。实现的一种方法是编写自己的自定义拆分迭代器。还有别的办法吗


共 (0) 个答案