2016-02-02 2 views
4

Я пытаюсь сформировать кокизное и последовательное понимание применения ленивой оценки в API потоков Java.Java-потоки lazy vs fusion vs short-circuiting

Вот что я в настоящее время понимаю:

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

Что я хочу сделать, это объединить все эти идеи и обеспечить, чтобы я не искажал ничего. Я нахожу это сложным, потому что всякий раз, когда я читаю какую-либо литературу о потоках Java, она продолжает говорить, что они ленивы или используют ленивую оценку, а затем очень много взаимозаменяемо начинает говорить об оптимизации, такие как слияние и короткое замыкание.

Так было бы правильно сказать следующее?

  • слитый как ленивым оценка была выполнена в потоке API - т.е. элемент потребляется, и операции сплавлены вместе, где это возможно. Я думаю, что если бы фьюжн не существовало, то, конечно, мы вернулись к нетерпеливой оценке, поскольку альтернативой было бы просто обработать все элементы для каждой промежуточной операции, прежде чем переходить на следующую?

  • короткое замыкание возможно без слияния или ленивой оценки, но очень помогает в контексте потоков посредством реализации этих двух принципов?

Буду признателен за дальнейшую проницательность и ясность в этом вопросе.

ответ

30

Что касается слияния. Давайте представим себе вот map операция:

.map(x -> x.squash()) 

Map

Это без гражданства, и он просто преобразует любой входной сигнал в соответствии с заданным алгоритмом (в нашем случае их давит). Теперь работа фильтра:

.filter(x -> x.getColor() != YELLOW) 

Filter

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

.forEach(System.out::println) 

Display

Он просто отображает элементы ввода в терминал.Слитый означает, что все промежуточные лица без операции объединены с терминала потребителя в одну операцию:

.map(x -> x.squash()) 
.filter(x -> x.getColor() != YELLOW) 
.forEach(System.out::println) 

Fuse

весь трубопровод слиты в единый Consumer, который подключен непосредственно к источнику. Когда каждый отдельный элемент обрабатывается, источник-разделитель просто выполняет комбинированный потребитель, потоковый конвейер ничего не перехватывает и не выполняет никакой дополнительной бухгалтерии. Это слияние. Fusion не зависит от короткого замыкания. Можно реализовать потоки без слияния (выполнить одну операцию, выполнить результат, выполнить следующую операцию, взять управление после каждой операции обратно в движок потока). Также возможно слияние без короткого замыкания.

+0

Ничего себе, лучшая визуализация потоков Java никогда! – apangin

+0

@ Тагир Валеев Спасибо за очень наглядный ответ - самое полезное. Я не чувствую, что вы ответили на несколько моих исходных вопросов, но это было: «Сплав - это то, как ленивая оценка была реализована в потоковом API. Я думаю, что если фьюжн не существовал, то, безусловно, мы были бы назад к нетерпеливой оценке »и, кроме того,« короткое замыкание возможно без слияния »? и если это так, то это будет просто нетерпеливая оценочная версия, которая только прекращает работу терминала, а не обрабатывает промежуточные операции. – Tranquility

+0

@Tranquility, я только что объяснил, что слияние - это способ объединения нескольких операционных систем вместе. Вы можете выполнять их шаг за шагом без слияния и все еще иметь ленивую оценку. –

Смежные вопросы