Понимание Java Сокращение потока - параллель против серии - PullRequest
0 голосов
/ 06 марта 2020

У меня есть Java код, который использует лямбда-выражения и потоки, чтобы найти среднее из списка целых чисел. Он использует Stream.reduce (...), чтобы найти сумму целых чисел, а затем вычисляет среднее значение. Код работает правильно, даже когда я удаляю параллель (). Может кто-нибудь объяснить, почему? Дополнительные вопросы после кода.

import java.util.Arrays;
import java.util.List;

public class Temp {
    public static void main(String [] args){
        //For example, consider a list of a *series* of numbers in increasing order.
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
        int n = numbers.get(numbers.size()-1);//n = 6 is the number of numbers in list.

        double expectedSum = (n * (n + 1))/2;//By mathematical formula for increasing series.

        Double sum = numbers
                //Take a stream of integers.
                .stream()
                //Split the stream into mini streams and calculate sum of each of mini stream.
                .parallel()
                //Reduce all the numbers in a stream to their sum.
                .reduce(
                        //start with a partial sum of 0.
                0.0,
                //For a stream, calculate the sum of all the numbers.
                (partialSum, nextNumber) -> partialSum + (double) nextNumber,
                //Add the sums of each mini stream.
                (onePartialSum, anotherPartialSum) -> (onePartialSum + anotherPartialSum)
        );

        System.out.println("Sum : expected value = " + expectedSum + ", actual value = " + sum);

        double expectedAverage = expectedSum/numbers.size();
        double average = sum/numbers.size();

        System.out.println("Average : expected value = " + expectedAverage + ", actual value = " + average);

    }
}

Вывод:

Sum : expected value = 21.0, actual value = 21.0
Average : expected value = 3.5, actual value = 3.5

Рассмотрим приведенный ниже код для функции, которая является BinaryOperator<U> combiner:

(onePartialSum, anotherPartialSum) -> (onePartialSum + anotherPartialSum)

Как эта линия на самом деле работает параллельно и непараллельно? Насколько я понимаю, параллельно он берет сумму каждого мини-потока и добавляет ее к «общей сумме». Это верно ? Когда поток не параллелен, тогда он делает ноль + общая сумма одного потока? Если да, то более точной заменой предыдущей строки кода будет (sum, onePartialSum) -> (sum + onePartialSum), где сумма уже установлена ​​в ноль ???

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...