Когда я выполнил вашу программу, я получил вывод:
clazz = 5 20 5
Добавление некоторых операторов печати:
IntStream.iterate(1,p->p+1)
.peek(a->{ System.out.println("add - " + a); clazz.add++; })
.limit(5)
.peek(a->{ System.out.println("after - " + a); clazz.after++; })
.parallel()
.forEach(i->{ System.out.println("d - " + i); ++clazz.d; });
Вывод:
add - 1025
add - 3073
add - 1
add - 6145
add - 2
add - 3074
add - 1026
add - 3075
add - 3
add - 6146
add - 6147
add - 4
add - 3076
add - 1027
add - 3077
add - 5
add - 6148
add - 6149
add - 1028
add - 1029
after - 3
after - 2
after - 5
d - 2
d - 3
d - 5
after - 1
after - 4
d - 1
d - 4
clazz = 5 20 5
Чтобы понять это, вот некоторые выдержки из документации.
java.util.stream
Промежуточные операции возвращают новый поток. Они всегда ленивы; выполнение промежуточной операции, такой как filter (), фактически не выполняет никакой фильтрации, но вместо этого создает новый поток, который при прохождении содержит элементы исходного потока, которые соответствуют данному предикату. Обход источника конвейера не начинается, пока не будет выполнена терминальная операция конвейера.
IntStream.peek
Для параллельных потоковых конвейеров действие может быть вызвано в любое время и в любом потоке, который элемент делает доступным в восходящей операции.
IntStream.limit
Хотя limit () обычно является дешевой операцией для последовательных потоковых конвейеров, она может быть довольно дорогой для упорядоченных параллельных конвейеров, особенно для больших значений maxSize, поскольку limit (n) ограничен, чтобы возвращать не только n элементов, но и первые n элементов в порядке встречи.
peek
не знает о limit
операции, поэтому она выполняется случайным образом N раз до выполнения limit
. Обратите внимание, что после печати строк с after -
и d -
строка с add -
не печатается.
Эти строки after -
и d -
печатают от 1 до 5, но ни peek
, ни forEach
не гарантируют порядок потока при работе с параллельными потоками.