Запуск следующего потока пример Java8:Java8 потоки последовательного и параллельного исполнения дают разные результаты?
System.out.println(Stream
.of("a", "b", "c", "d", "e", "f")
.reduce("", (s1, s2) -> s1 + "/" + s2)
);
выходы:
/a/b/c/d/e/f
Который есть - конечно - не удивительно. Благодаря http://docs.oracle.com/javase/8/docs/api/index.html?overview-summary.html не должно иметь значения поток выполняется ли последовательно или параллельно:
для операций, определенных как явно недетерминирован, таких как findAny() за исключением того, выполняется ли поток последовательно или параллельно, не должны изменить результат вычисления.
AFAIK reduce()
детерминирована и (s1, s2) -> s1 + "/" + s2
ассоциативно, так что добавление parallel()
должно дать тот же результат:
System.out.println(Stream
.of("a", "b", "c", "d", "e", "f")
.parallel()
.reduce("", (s1, s2) -> s1 + "/" + s2)
);
Однако результат на моей машине:
/a//b//c//d//e//f
Что здесь не так ?
BTW: использование (предпочтительный) .collect(Collectors.joining("/"))
вместо дает тот же результат a/b/c/d/e/f
для последовательного и параллельного выполнения.
детали JVM:
java.specification.version: 1.8
java.version: 1.8.0_31
java.vm.version: 25.31-b07
java.runtime.version: 1.8.0_31-b13
На самом деле это [специально указано] (http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-java.util.function.BinaryOperator -), что если ваш 'BinaryOperator' является [Ассоциативным] (http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#Associativity), то это должно работать с параллельные потоки. – OldCurmudgeon
В дополнение к тому, чтобы не следовать правилам сокращения, как указывали другие ответчики, есть более простой способ сделать то, что вы делаете: 'stream.collect (joining ("/"))' –