一道关于Spliterator的问题,乍一看并不直接。
在流(Stream)中,.parallel()
会改变流处理的行为。然而,我本来以为从Sequential Stream和Parallel Stream创建出来的Spliterator是一样的。例如,在Sequential Stream中,通常不会调用.trySplit()
,而在Parallel Stream中,则会为了将切割后的Spliterator交给另一个线程。
stream.spliterator()
与stream.parallel().spliterator()
之间的区别:
They may have different characteristics:
Stream.of(1L, 2L, 3L).limit(2); // ORDERED Stream.of(1L, 2L, 3L).limit(2).parallel(); // SUBSIZED, SIZED, ORDERED
看起来又有一个无意义的流分割迭代器特征策略(并行计算似乎更好)在这里讨论:深入理解Java 8和Java 9中的Spliterator特征
They may have different behaviour in terms of splitting using
.trySplit()
:Stream.of(1L, 2L, 3L); // NON NULL Stream.of(1L, 2L, 3L).limit(2); // NULL Stream.of(1L, 2L, 3L).limit(2).parallel(); // NON NULL
为什么最后两个行为不同?如果我想拆分一个顺序流,为什么我不能这样做?(例如,快速处理时丢弃其中一个拆分可能有用)。
Big impacts when transforming a spliterators to a stream:
spliterator = Stream.of(1L, 2L, 3L).limit(2).spliterator(); stream = StreamSupport.stream(spliterator, true); // No parallel processing!
.trySplit()
返回null)。当稍后需要转换回流时,该流将不会受益于并行处理。真遗憾。重要问题是:作为解决方法,总是在调用
.spliterator()
之前将流转换为并行流的主要影响是什么?// Supports activation of parallel processing later
public static <T> Stream<T> myOperation(Stream<T> stream) {
boolean isParallel = stream.isParallel();
Spliterator<T> spliterator = stream.parallel().spliterator();
return StreamSupport.stream(new Spliterator<T>() {
// My implementation of the interface here (omitted for clarity)
}, isParallel).onClose(stream::close);
}
// Now I have the option to use parallel processing when needed:
myOperation(stream).skip(1).parallel()...
parallel()
,因为它可能会意外地并行执行某些操作(比如排序),从而消耗更多的 CPU 核心”,这部分回答了你的问题(总是将流转换为并行产生的主要影响)... - Holger.trySplit()
)。为什么需要执行这些操作?有没有任何地方可以获取该信息?(顺便说一句:这就是我正在寻找的答案) - Tet