Stream.forEach()总是并行工作吗?

ARX*_*ARX 8 java java-stream

使用Streams聚合时,Brian Goetz比较使用Stream.collect()填充集合并使用Stream.forEach()执行相同操作,使用以下两个片段:

Set<String> uniqueStrings = strings.stream()
                                   .collect(HashSet::new,
                                            HashSet::add,
                                            HashSet::addAll);
Run Code Online (Sandbox Code Playgroud)

和,

Set<String> set = new HashSet<>();
strings.stream().forEach(s -> set.add(s));
Run Code Online (Sandbox Code Playgroud)

然后他解释说:

关键的区别在于,使用forEach()版本,多个线程同时尝试访问单个结果容器,而使用并行collect(),每个线程都有自己的本地结果容器,其结果随后合并.

据我所知,只有当流是并行的时,多个线程才会在forEach()情况下工作.但是,在给出的示例中,forEach()在顺序流上运行(不调用parallelStream()).

那么,forEach()是否始终并行工作,或者代码片段应该调用parallelStream()而不是stream().(或者我错过了什么?)

Jea*_*sky 8

不,如果流不是并行的,则forEach()不会并行化.我认为他为了讨论而简化了这个例子.

作为证据,此代码位于AbstractPipeline类的evaluate方法(从forEach调用)中

 return isParallel()
               ? terminalOp.evaluateParallel(this, sourceSpliterator(terminalOp.getOpFlags()))
               : terminalOp.evaluateSequential(this, sourceSpliterator(terminalOp.getOpFlags()));
Run Code Online (Sandbox Code Playgroud)