Java 并行流 forEach 完成

ssh*_*har 4 java multithreading java-stream

我想澄清一下 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");
}
Run Code Online (Sandbox Code Playgroud)

重复的试验总是在最后打印出“应该发生在最后”,如下所示。这可能会发生,因为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
Run Code Online (Sandbox Code Playgroud)

ama*_*nin 6

终端操作不是异步的。这意味着只有在 forEach 终止后, Java 才会将控制权交还给调用线程。因此,您在forEach之后打印的内容必然会在控制台中打印。

但请注意,如果您使用java.util.Logger API 而不是System.out,则输出排序将无法预测,因为日志记录 API 本身无法(主要出于性能原因)保证输出的排序。

关于流操作的进一步阅读:Oracle官方文档