乍一看并不直截了当的关于拆分器的问题。
在流中,.parallel()
更改处理流的行为。但是,我期望从顺序流和并行流创建的拆分器是相同的。例如,通常在顺序流中,.trySplit()
从不调用,而在并行流中,它是为了将拆分拆分器移交给另一个线程。
stream.spliterator()
vs之间的区别stream.parallel().spliterator()
:
它们可能具有不同的特征:
Stream.of(1L, 2L, 3L).limit(2); // ORDERED Stream.of(1L, 2L, 3L).limit(2).parallel(); // SUBSIZED, SIZED, ORDERED
似乎这里讨论了另一个无意义的流拆分器特征策略(并行似乎更好地计算):Understanding deep spliterator features in java 8 and java 9
它们在使用拆分方面可能有不同的行为
.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
为什么最后两个有不同的行为?如果我愿意,为什么我不能拆分顺序流?(例如,丢弃其中一个拆分以进行快速处理可能很有用)。
将拆分器转换为流时的重大影响:
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()...