Sobes.tech
Junior — Middle

Kokiais metodais galima įgyvendinti masyvo elementų sumos skaičiavimą lygiagrečiai naudojant ForkJoinPool?

sobes.tech AI

Atsakymas iš AI

Norint atlikti masyvo elementų sumos skaičiavimą lygiagrečiai naudojant ForkJoinPool, galima įgyvendinti rekursinę užduotį, kuri dalija masyvą į dalis ir skaičiuoja jų sumą lygiagrečiai.

Pagrindinė idėja:

  • Jei submasyvo dydis yra mažas, skaičiuojame sumą tiesiogiai.
  • Kitaip dalijame submasyvą į dvi dalis, kuriame sukuriame dvi užduotis, vykdome jas lygiagrečiai ir sujungiame rezultatus.

Pavyzdys Java kalba naudojant RecursiveTask<Integer>:

import java.util.concurrent.*;

public class SumTask extends RecursiveTask<Integer> {
    private static final int THRESHOLD = 1000;
    private int[] array;
    private int start, end;

    public SumTask(int[] array, int start, int end) {
        this.array = array;
        this.start = start;
        this.end = end;
    }

    @Override
    protected Integer compute() {
        int length = end - start;
        if (length <= THRESHOLD) {
            int sum = 0;
            for (int i = start; i < end; i++) {
                sum += array[i];
            }
            return sum;
        } else {
            int mid = start + length / 2;
            SumTask leftTask = new SumTask(array, start, mid);
            SumTask rightTask = new SumTask(array, mid, end);
            leftTask.fork(); // paleidžiame kairiąją užduotį asinchroniškai
            int rightResult = rightTask.compute(); // skaičiuojame dešiniąją užduotį dabartiniame sraute
            int leftResult = leftTask.join(); // laukiame kairiosios užduoties rezultato
            return leftResult + rightResult;
        }
    }
}

// Naudojimas:
// ForkJoinPool pool = new ForkJoinPool();
// int[] data = ...;
// int totalSum = pool.invoke(new SumTask(data, 0, data.length));

Šis požiūris efektyviai išnaudoja kelių gijų galimybes spartinant didelio masyvo sumos skaičiavimą.