Как обеспечить порядок обработки в потоках java8?


Я хочу обрабатывать списки внутри XML объект java. Я должен обеспечить обработку всех элементов, чтобы я их получил.

поэтому я должен позвонить sequential в каждом stream использовать? list.stream().sequential().filter().forEach()

или достаточно просто использовать поток, пока я не использовать параллелизм? list.stream().filter().forEach()

2 92

2 ответа:

вы задаете неправильный вопрос. Вы спрашиваете о sequential и parallel в то время как вы хотите обрабатывать элементы в целях, так что вы должны спросить о заказ. Если у вас есть приказал поток и выполнение операций, которые гарантируют поддержание порядка, не имеет значения, обрабатывается ли поток параллельно или последовательно; реализация будет поддерживать порядок.

упорядоченное свойство отличается от параллельный против последовательного. Например, если вы позвоните stream() на HashSet поток будет неупорядочен при вызове stream() на List возвращает упорядоченный поток. Обратите внимание, что вы можете позвонить unordered() чтобы освободить контракт на заказ и потенциально повысить производительность. Как только поток не имеет упорядочения, нет никакого способа восстановить порядок. (Единственный способ превратить неупорядоченный поток в упорядоченный-это вызвать sorted, однако, полученный порядок не обязательно является оригинальным порядок.)

см. также "заказ" раздел на java.util.stream пакета документации.

чтобы обеспечить поддержание порядка на протяжении всей операции потока, вы должны изучить документацию источника потока, все промежуточные операции и терминальную операцию для того, поддерживают ли они порядок или нет (или есть ли у источника заказ в первую очередь).

это может быть очень тонким, например,Stream.iterate(T,UnaryOperator) создает упорядоченный поток, в то время как Stream.generate(Supplier) создает ненумерованный поток. Обратите внимание, что вы также сделали распространенную ошибку в своем вопросе как forEachне сохранить заказ. Вы должны использовать forEachOrdered если вы хотите обрабатывать элементы потока в гарантированный заказ.

так что если ваш list в вашем вопросе действительно java.util.List, его stream() метод возвратить приказал Stream и filter не будет изменять порядок. Так что если вы позвоните list.stream().filter() .forEachOrdered(), все элементы будут обрабатываться последовательно по порядку, тогда как для list.parallelStream().filter().forEachOrdered() элементы могут обрабатываться параллельно (например, фильтром), но терминальное действие все равно будет вызываться по порядку (что, очевидно, уменьшит преимущество параллельного выполнения).

если вы, например, используете операцию как

List<…> result=inputList.parallelStream().map(…).filter(…).collect(Collectors.toList());

вся операция может принести пользу из параллельного выполнения, но результирующий список всегда будет в правильном порядке, независимо от того, используете ли вы параллельный или последовательный поток.

список.поток.)(последовательный.)(фильтр.)(forEach ()

всегда будет обрабатывать список в порядке, как и сам список упорядочен.

однако если мы используем тег

список.поток.)(параллельные()

тогда порядок не гарантируется для остальных операций.