Sobes.tech
Middle+

Фреймворки Fork/Join چیست و چگونه در جاوا استفاده می‌شود؟

sobes.tech AI

Ҷавоб аз AI

Фреймворки Fork/Join — инҷо як татбиқи махсуси рамзи Executor мебошад, ки барои тақсим кардани самараноки вазифаҳо, ки метавонанд ба таври рекурсивӣ ба вазифаҳои хурдтар тақсим шаванд ва сипас натиҷаҳои онҳоро пайваст (join) кунанд, пешбинӣ шудааст. Он асос ёфтааст ба принсипи "ҳисоб кардан ва ҳукмронӣ".

Компонентҳои асосӣ:

  • ForkJoinPool: Пул аз сӯрохҳо, ки иҷрои вазифаҳоро идора мекунад. Механизми "work-stealing"-ро истифода мебарад, ки дар он сӯрохҳои ғайрифаъол метавонанд вазифаҳоро аз сӯрохҳои машғул ба даст оранд.
  • ForkJoinTask: Класс абстрактӣ, ки вазифаи иҷрошаванда дар ин рамзро намояндагӣ мекунад. Ду навъ дорад:
    • RecursiveAction: Вазифае, ки натиҷа намегузорад.
    • RecursiveTask<V>: Вазифае, ки натиҷа аз навъи V медиҳад.

Истифода:

  1. Классе сохта мешавад, ки аз RecursiveAction ё RecursiveTask мерос мегирад.
  2. Методи compute() навишта мешавад. Дар ин метод логикаи вазифа тасвир мешавад:
    • Агар вазифа кофӣ хурд бошад (аз як марз муайян), мустақим иҷро мешавад.
    • Дар акси ҳол, вазифа ба вазифаҳои хурдтар тақсим мешавад ва бо истифода аз fork() ба таври асинхронӣ оғоз мегардад.
    • Вақт барои анҷоми вазифаҳои хурдтар бо join() интизор мешавад ва натиҷаҳо пайваст карда мешаванд.
  3. Нусхаи ForkJoinPool сохта мешавад.
  4. Вазифа ба пул бо истифода аз invoke() ё submit() супурда мешавад.

Масалан:

import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;

class SumArrayTask extends RecursiveTask<Long> {
    private final long[] array;
    private final int start;
    private final int end;
    private static final int THRESHOLD = 1000; // Марз

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

    @Override
    protected Long compute() {
        if (end - start <= THRESHOLD) {
            // Ҳисоботи мустақим барои доираҳои хурд
            long sum = 0;
            for (int i = start; i < end; i++) {
                sum += array[i];
            }
            return sum;
        } else {
            // Тақсим кардани вазифа
            int mid = start + (end - start) / 2;
            SumArrayTask leftTask = new SumArrayTask(array, start, mid);
            SumArrayTask rightTask = new SumArrayTask(array, mid, end);

            // Иҷрои асинхронӣ
            leftTask.fork();
            Long rightResult = rightTask.compute();
            Long leftResult = leftTask.join();

            // Пайваст кардани натиҷаҳо
            return leftResult + rightResult;
        }
    }
}

// Истифода дар коди асосӣ
// long[] data = new long[10000]; // Датаҳои ибтидоӣ
// // пур кардани data
// ForkJoinPool pool = new ForkJoinPool();
// long sum = pool.invoke(new SumArrayTask(data, 0, data.length));
// pool.shutdown(); // Баста кардани пул пас аз истифода

Афзалиятҳо:

  • Идоракунии автоматии пулҳои сӯрохҳо.
  • тақсимоти самараноки бор дар асоси "work-stealing".
  • Беҳтар шудани иҷро барои вазифаҳои "ҳисоб кардан ва ҳукмронӣ".

Норасоиҳо:

  • Барои ҳама намудҳои вазифаҳои параллелӣ мувофиқ нест.
  • Мумкин аст, ки дар иҷрои он мураккабтар бошад дар муқоиса бо дигар роҳҳо барои вазифаҳои оддӣ.