Рубрики
Без рубрики

Примеры фреймворка Java Fork/Join

– Примеры фреймворка Java Fork/Join

Платформа fork/join доступна с Java 7, чтобы упростить написание параллельных программ. Мы можем реализовать фреймворк fork/join, расширив либо рекурсивную задачу , либо Рекурсивное действие

1. Вилка/Соединение – Рекурсивная задача

Пример соединения вилки для суммирования всех чисел из диапазона.

package com.mkyong.concurrency.forkjoin;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;

public class ForkJoinAdd extends RecursiveTask {

    private final long[] numbers;
    private final int start;
    private final int end;
    public static final long threshold = 10_000;

    public ForkJoinAdd(long[] numbers) {
        this(numbers, 0, numbers.length);
    }

    private ForkJoinAdd(long[] numbers, int start, int end) {
        this.numbers = numbers;
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {

        int length = end - start;
        if (length <= threshold) {
            return add();
        }

        ForkJoinAdd firstTask = new ForkJoinAdd(numbers, start, start + length / 2);
        firstTask.fork(); //start asynchronously

        ForkJoinAdd secondTask = new ForkJoinAdd(numbers, start + length / 2, end);

        Long secondTaskResult = secondTask.compute();
        Long firstTaskResult = firstTask.join();

        return firstTaskResult + secondTaskResult;

    }

    private long add() {
        long result = 0;
        for (int i = start; i < end; i++) {
            result += numbers[i];
        }
        return result;
    }

    public static long startForkJoinSum(long n) {
        long[] numbers = LongStream.rangeClosed(1, n).toArray();
        ForkJoinTask task = new ForkJoinAdd(numbers);
        return new ForkJoinPool().invoke(task);
    }

}

Запустите его. Суммируйте все числа от 1 до 1 миллиона.

package com.mkyong.concurrency.forkjoin;

public class Main {

    public static void main(String[] args) {

        System.out.println(ForkJoinAdd.startForkJoinSum(1_000_000));
		
    }

}

Выход

500000500000

2. Вилка/Соединение – рекурсивное действие

Пример соединения вилки, чтобы найти число Фибоначчи с помощью рекурсивного цикла.

package com.mkyong.concurrency.forkjoin;

import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveAction;

public class ForkJoinFibonacci extends RecursiveAction {

    private static final long threshold = 10;
    private volatile long number;

    public ForkJoinFibonacci(long number) {
        this.number = number;
    }

    public long getNumber() {
        return number;
    }

    @Override
    protected void compute() {
        long n = number;
        if (n <= threshold) {
            number = fib(n);
        } else {
            ForkJoinFibonacci f1 = new ForkJoinFibonacci(n - 1);
            ForkJoinFibonacci f2 = new ForkJoinFibonacci(n - 2);
            ForkJoinTask.invokeAll(f1, f2);
            number = f1.number + f2.number;
        }
    }

    private static long fib(long n) {
        if (n <= 1) return n;
        else return fib(n - 1) + fib(n - 2);
    }

}

Запустите его, найдите 50-е число Фибоначчи.

package com.mkyong.concurrency.forkjoin;

import java.util.concurrent.ForkJoinPool;

public class Main {

    public static void main(String[] args) {

        ForkJoinFibonacci task = new ForkJoinFibonacci(50);
        new ForkJoinPool().invoke(task);

        System.out.println(task.getNumber());

    }

}

Выход

12586269025

Скачать Исходный Код

Рекомендации

  1. Oracle – Вилка/Присоединение
  2. Вилка Java – Присоединиться к бедствию
  3. Дуг Ли – Развилка Java/Платформа для объединения
  4. Википедия – Число Фибоначчи
  5. Примеры Фибоначчи Java
  6. Рекурсивная задача javadoc
  7. JAVADOC рекурсивного действия

Оригинал: “https://mkyong.com/java/java-fork-join-framework-examples/”