Ответ 1
В основном реализация Collection.parallelStream()
по умолчанию создает параллельный поток. Реализация выглядит следующим образом:
default Stream<E> parallelStream() {
return StreamSupport.stream(spliterator(), true);
}
Но это метод по умолчанию, для какого-то класса реализации совершенно справедливо предоставить другую реализацию для создания последовательного потока. Например, предположим, что я создаю SequentialArrayList
:
class MySequentialArrayList extends ArrayList<String> {
@Override
public Stream<String> parallelStream() {
return StreamSupport.stream(spliterator(), false);
}
}
Для объекта этого класса следующий код напечатает false
, как ожидалось:
ArrayList<String> arrayList = new MySequentialArrayList();
System.out.println(arrayList.parallelStream().isParallel());
В этом случае вызов метода BaseStream#parallel()
гарантирует, что возвращенный поток всегда параллелен. Либо он уже был параллелен, либо параллелен, установив для поля parallel
значение true
:
public final S parallel() {
sourceStage.parallel = true;
return (S) this;
}
Это реализация метода AbstractPipeline#parallel()
.
Итак, следующий код для одного и того же объекта напечатает true
:
System.out.println(arrayList.parallelStream().parallel().isParallel());
Но если поток уже параллелен, то да это дополнительный вызов метода, но это гарантирует, что вы всегда получите параллельный поток. Я еще не вникал в распараллеливание потоков, поэтому я не могу прокомментировать, какая коллекция или в каких случаях parallelStream()
предоставит вам последовательный поток.