[Thread pool] fork and join

Table of contents

1. Concept

  • 1. Fork/Join is a new thread pool implementation added by jdk1.7
  • 2. It embodies a kind of divide-and-conquer thinking
  • 3. Suitable for cpu-intensive operations that can split tasks
  • 4. Task splitting is to split a large task into small tasks with the same algorithm, until it cannot be split and can be solved directly
  • 5. Calculations related to recursion, such as merge sort and Fibonacci sequence, can be solved by dividing and conquering
  • 6. Fork/Join adds multi-threading on the basis of divide and conquer, which can decompose and merge each task to different threads to complete, further improving computing efficiency
  • 7. Fork/Join will create a thread pool with the same size as the number of CPU cores by default, which is a CPU-intensive task

Two, use

  • 1. The task submitted to the Fork/Join thread pool needs to inherit RecursiveTask (with return value) or RecursiveAction (without return value)
  • 2. ForkJoinPool has no parameter structure, and the number of threads is the number of cpu cores
  • 3. The fork method allows a thread in the thread pool to execute
  • 4. join method to obtain task results

3. Code example

package com.learning.threadpool.forkjoin;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

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

/**
 * 求1-n之间整数的和
 */
@Data
@AllArgsConstructor
@Slf4j
public class RecursiveTaskLearning extends RecursiveTask<Integer> {

    private int n;

    @Override
    protected Integer compute() {
        if(n == 1){
            log.info("join() {}", n);
            return n;
        }
        // 将任务进行拆分(fork)
        RecursiveTaskLearning recursiveTaskLearning = new RecursiveTaskLearning(n - 1);
        // 拆分,让线程池的一个线程去执行
        recursiveTaskLearning.fork();
        // 获取任务结果
        int result = n + recursiveTaskLearning.join();
        log.info("join() {} + {} = {}", n, recursiveTaskLearning, result);
        return result;
    }

    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool(4);
        Integer invoke = pool.invoke(new RecursiveTaskLearning(5));
        System.out.println(invoke);
    }
}

package com.learning.threadpool.forkjoin;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

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

/**
 * 求1-n之间整数的和
 */
@Data
@AllArgsConstructor
@Slf4j
public class RecursiveTaskLearning_2 extends RecursiveTask<Integer> {

    private int begin;

    private int end;

    @Override
    protected Integer compute() {
        if(begin == end){
            log.info("join() {}", begin);
            return begin;
        }
        if(end - begin == 1){
            log.info("join() {} + {} = {}", begin, end, begin + end);
            return begin + end;
        }
        int mid = (begin + end) / 2;
        RecursiveTaskLearning_2 recursiveTaskLearning1 = new RecursiveTaskLearning_2(begin, mid);
        // 拆分,让线程池的一个线程去执行
        recursiveTaskLearning1.fork();
        RecursiveTaskLearning_2 recursiveTaskLearning2 = new RecursiveTaskLearning_2(mid + 1, end);
        // 拆分,让线程池的一个线程去执行
        recursiveTaskLearning2.fork();
        log.info("fork() {} + {} = ?", recursiveTaskLearning1, recursiveTaskLearning2);
        // 获取任务结果
        int result = recursiveTaskLearning1.join() + recursiveTaskLearning2.join();
        return result;
    }

    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool(4);
        Integer invoke = pool.invoke(new RecursiveTaskLearning_2(1, 5));
        System.out.println(invoke);
    }
}

Guess you like

Origin blog.csdn.net/qq_32088869/article/details/131869679