Java并行流forEach的完成

4

我想澄清一下Java并行流的行为。如果我像下面展示的那样使用并行流,我能否将其视为保证在所有并行任务执行完毕之后才会打印代码中显示的“应该发生在最后”的那行?

public static void main(String[] args) {
    Stream.of(1, 2, 3, 5, 7, 8, 9, 10, 11, 23, 399, 939).parallel().forEach(
        integer -> System.out
            .println(Thread.currentThread().getName() + ", for number " + integer));
    System.out.println("Should happen at the end");
}

这些重复的试验总是可预见地在最后打印出“应该发生在结尾”,如下所示。这可能是因为main线程也用来处理一些请求。在某些情况下,是否可能不使用main线程,在那种情况下,“应该发生在结尾”会在所有ForkJoinPool.commonPool-worker完成执行任务之前打印出来?
main, for number 7
main, for number 6
ForkJoinPool.commonPool-worker-9, for number 3
ForkJoinPool.commonPool-worker-9, for number 4
ForkJoinPool.commonPool-worker-4, for number 1
ForkJoinPool.commonPool-worker-4, for number 10
ForkJoinPool.commonPool-worker-2, for number 2
ForkJoinPool.commonPool-worker-11, for number 5
ForkJoinPool.commonPool-worker-9, for number 8
main, for number 9
Should happen at the end
1个回答

6

流的终端操作不是异步的。这意味着仅当 forEach 终止后,Java 才会将控制权返回给调用线程。因此,在 forEach 之后打印的内容必定在控制台中打印。

但请注意,如果您使用的是 java.util.Logger API 而不是 System.out,输出顺序就不那么可预测了,因为日志记录 API 本身主要出于性能原因不能保证输出的顺序。

有关流操作的进一步阅读,请参阅Oracle 官方文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接