What is the forkjoin framework in the concurrent programming series?

Time:2022-5-31

What is the forkjoin framework in the concurrent programming series?

1. What is the forkjoin framework

The forkjoin framework is provided in the JUC package of Java. It is used to handle some heavy tasks. It will divide the big task into multiple small tasks. After the completion of multiple small tasks, the results will be summarized to the result, reflecting the idea of “divide and rule”. The first step is to split the fork task into several small tasks; The second step, merge join, will merge the processing results of small tasks into one result.

What is the forkjoin framework in the concurrent programming series?

Insert picture description here

2、ForkJoinTask

ForkJoinTaskyesForkJoinThe task API provided by the framework,ForkJoinTaskIs an abstract class with two main implementation classes,RecursiveTaskandRecursiveActionWhereRecursiveTaskandRecursiveActionThe main difference is that,RecursiveActionNo return value, andRecursiveTaskIt has a return value

What is the forkjoin framework in the concurrent programming series?

Insert picture description here

3、ForkJoinPool

The forkjoinpool class is the thread pool implementation of the forkjoin framework, based on the executorservice interface. This thread pool was added only in jdk1.7 to manage threads and execute forkjoin tasks. For the use of thread pool, we often use ThreadPoolExecutor. You can see from the UML class diagram in the idea that forkjoinpool and ThreadPoolExecutor are similar in implementation.

What is the forkjoin framework in the concurrent programming series?

Insert picture description here
ForkJoinPool()
ForkJoinPool(int parallelism)
ForkJoinPool(int parallelism, ForkJoinWorkerThreadFactory factory,
 UncaughtExceptionHandler handler, boolean asyncMode)

Several important parameters:

  • Parallelism: parallelism. Parallel execution threads can be specified or not specified. If not specified, available threads are created according to the number of CPU cores
  • Forkjoinworkerthreadfactory: factory implementation for creating threads
  • Uncaughtexceptionhandler: callback handling interrupted because of unknown exception
  • Asyncmode: whether it is asynchronous. The default is false

When in use, you can directly create a forkjoinpool without parameters. By default, the specified thread parallelism isRuntime.getRunTime().availableProcessors();, indicating the number of available threads created according to the number of CPU cores

ForkJoinPool forkJoinPool = new ForkJoinPool();
ArraySortTask task = new ArraySortTask(array , 0 , size);
forkJoinPool.submit(task);
task.get();

You can also specify the parallelism by passing parameterspublic ForkJoinPool(int parallelism), parallelism, parallel execution of several threads

There are several ways to add a forkjoin task to the frokjoinpool thread pool

  • Execute (): call its fork method to split work among multiple threads.
  • Invoke (): invoke the invoke method on the forkjoinpool thread pool
  • Submit(): returns a future object, which can be monitored by future, and returns the result after the task is completed

4. Print Fibonacci series

The forkjoin framework can be used in some recursive traversal scenarios. You can be familiar with Fibonacci sequence, because it is often asked in the interview that the result of the last item is equal to the sum of the first two items

package com.example.concurrent.forkjoin;

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

/**
 * <pre>
 *Fibonacci sequence
 * </pre>
 * <p>
 * <pre>
 * @author nicky.ma
 *Modification record
 *Modified version: modified by: modified date: October 12, 2021 16:22 modified content:
 * </pre>
 */
public class Fibonacci extends RecursiveTask<Integer>{

    private int n;

    public Fibonacci(int n) {
        this.n = n;
    }

    @Override
    protected Integer compute() {
        if (n <= 1)
            return n;
        Fibonacci f1 = new Fibonacci(n - 1);
        f1.fork();
        Fibonacci f2 = new Fibonacci(n - 2);
        f2.fork();
        return f1.join() + f2.join();
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ForkJoinPool pool = new ForkJoinPool();
        for (int i = 0; i< 10; i++) {
            ForkJoinTask task = pool.submit(new Fibonacci(i));
            System.out.println(task.get());
        }
    }
}

5. Forkjoin merge sort

Interview question: quickly sort an array with a length of millions

Difficulty: merge sort can be used. How can multithreads organize and implement merge sort

package com.example.concurrent.forkjoin;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

/**
 * <pre>
 *Large array sort
 * </pre>
 * <p>
 * <pre>
 * @author mazq
 *Modification record
 *Modified version: modified by: modified date: October 12, 2021 17:04 modified content:
 * </pre>
 */
public class ArraySortTask extends RecursiveAction{

    final long[] array; final int lo, hi;
    ArraySortTask(long[] array, int lo, int hi) {
        this.array = array; this.lo = lo; this.hi = hi;
    }
    ArraySortTask(long[] array) { this(array, 0, array.length); }

    @Override
    protected void compute() {
        if (hi - lo < THRESHOLD)
            //Less than the threshold, use arrays Sort quick platoon
            sortSequentially(lo, hi);
        else {
            /*Merge sort*/
            //Take intermediate value
            int mid = (lo + hi) >>> 1;
            //Split task
            invokeAll(new ArraySortTask(array, lo, mid),
                    new ArraySortTask(array, mid, hi));
            //Merging result
            merge(lo, mid, hi);
        }
    }

    // implementation details follow:
    static final int THRESHOLD = 1000;
    void sortSequentially(int lo, int hi) {
        Arrays.sort(array, lo, hi);
    }

    void merge(int lo, int mid, int hi) {
        long[] buf = Arrays.copyOfRange(array, lo, mid);
        for (int i = 0, j = lo, k = mid; i < buf.length; j++)
            array[j] = (k == hi || buf[i] < array[k]) ?
                    buf[i++] : array[k++];
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        int size = 10_000;
        long[] array = new long[size];
        Random random = new Random();
        for (int i = 0; i< size; i++) {
            array[i] = random.nextInt();
        }

        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ArraySortTask task = new ArraySortTask(array , 0 , size);
        forkJoinPool.submit(task);
        task.get();

        for (long a : array) {
            System.out.println(a);
        }
    }
}

References

Recommended Today

Spring JDBC usage steps

Spring JDBC usage steps *It is a simple JDBC encapsulation of the spring box, providing a JDBCTemplate object to simplify the development of JDBC *step: 1. Import the package commons-logging-1.2.jar spring-beans-5.0.0.RELEASE.jar spring-core-5.0.0.RELEASE.jaar spring-jdbc-5.0.RELEASE.jar spring-tx-5.0.0.RELEASE.jar 2. Create a Jdbc Template object, depending on the data source DataSource *Jdbc Template template=new Jdbc Template(DataSource datasource) 3. Call the […]