Существует ли хороший вариант использования для skip() в параллельных потоках?
Отредактировано в сентябре 2015
Когда я первоначально задавал этот вопрос в феврале 2015 года, поведение, о котором сообщалось в связанном вопросе, было нелогичным, хотя и допускалось спецификацией (несмотря на некоторые небольшие несоответствия в документах).
Однако Тагир Валеев задал новый вопрос в июне 2015 года, где, как мне кажется, он четко продемонстрировал, что поведение, о котором сообщалось в этом вопросе, было на самом деле ошибкой. Брейн Гетц ответил на его вопрос и признал, что было ошибкой не остановить обратное распространение UNORDERED
характеристикаStream
на skip()
когда запускается терминальной операцией, которая не была вынуждена соблюдать порядок встречи элементов (например, forEach()
). Кроме того, в комментариях к собственному ответу он поделился ссылкой на опубликованную проблему в системе отслеживания ошибок JDK.
Статус проблемы теперь решен, и его версия исправления 9, что означает, что исправление будет доступно в JDK9. Однакоон также был перенесен в обновление 60 JDK8, сборка 22.
Итак, начиная с JDK8u60-b22, этот вопрос больше не имеет смысла, так как теперьskip()
вести себя согласно интуиции даже на параллельных потоках.
Мой оригинальный вопрос следует...
Недавно у меня была дискуссия с некоторыми коллегами по этому поводу. Я говорю, что это совершенно бесполезно использоватьskip()
на параллельных потоках, так как, кажется, нет хорошего варианта использования для этого. Они рассказывают мне об увеличении производительности, обработке пула FJ, количестве ядер, доступных для jvm, и т. Д., Но они не могут дать мне никакого практического примера его использования.
Существует ли хороший вариант использования дляskip()
на параллельных потоках?
Смотрите этот вопрос здесь на SO.Пожалуйста, прочитайте вопрос и ответы, а также комментарии, потому что там есть множество хороших аргументов.
1 ответ
Выбор между последовательным и параллельным просто является стратегией исполнения. Вариант параллелизма существует так, что, если специфика проблемы (размер проблемы, выбор потоковых операций, вычислительная работа для каждого элемента, доступные процессоры, пропускная способность памяти и т. Д.) Позволяют, то выигрыш в производительности может быть достигнут при параллельной работе. Не все комбинации этих особенностей позволят повысить производительность (а некоторые могут даже наложить штраф), поэтому мы оставляем пользователю право отдельно определять операции из стратегии выполнения.
Для таких операций, как skip()
или же limit()
, которые неразрывно связаны с порядком, действительно трудно извлечь много параллелизма, но это возможно; это обычно происходит, когда вычислительная работа на элемент (часто называемая 'Q') очень высока.
Такие случаи, вероятно, редки (что может быть вашей точкой); это не делает комбинацию режима работы и выполнения "бесполезной", просто ограниченную полезность. Но нельзя разрабатывать API с несколькими измерениями (операциями, режимами выполнения), основанными на комбинациях, которые можно себе представить; Предполагая, что каждая комбинация имеет разумную семантику (что и происходит в этом случае), лучше всего разрешить все операции во всех режимах и позволить пользователям решать, что для них полезно.