【框架】说一说 Fork/Join?

SueWakeup

个人主页:SueWakeup

系列专栏:学习Java框架

个性签名:人生乏味啊,我欲令之光怪陆离


本文封面由 凯楠📷 友情赞助

目录

前言

[什么是 Fork?](#什么是 Fork?)

[什么是 Join?](#什么是 Join?)

[Fork/Join 的核心组件](#Fork/Join 的核心组件)

[Fork/Join 的工作流程](#Fork/Join 的工作流程)

[1. 创建 ForkJoinPool](#1. 创建 ForkJoinPool)

[2. 提交任务](#2. 提交任务)

[3. 执行任务](#3. 执行任务)

[4. 任务拆分与执行](#4. 任务拆分与执行)

[5. 结果合并](#5. 结果合并)

[Fork/Join 计算斐波那契数列](#Fork/Join 计算斐波那契数列)

注:手机端浏览本文章可能会出现 "目录"无法有效展示的情况,请谅解,点击侧栏目录进行跳转


前言

Fork/Join 框架是 Java 7中引入的一个并行(同时)计算框架,主要用于处理递归式任务。


什么是 Fork?

Fork 是指将一个大任务拆分成多个小任务并行(同时)执行


什么是 Join?

Join 是指等待这些小任务执行完成,并将它们的结果合并


Fork/Join 的核心组件

  • ForkJoinPool:整个框架的线程池,负责管理工作线程以及任务的调度和执行

ForkJoinPool 示意图

  • ForkJoinTask:可分解的任务,一般情况下通过基础 RecursiveTask(有返回结果)或 RecursiveAtion(无返回结果)来实现具体的任务

ForkJoinTask 示意图

  • ForkJoinWorkerThread :工作线程,负责执行 ForkJoinTask 中的任务

ForkJoinWorkerThread 示意图


Fork/Join 的工作流程

1. 创建 ForkJoinPool

  • 创建一个 ForkJoinPool 对象,一般情况下使用默认的构造函数创建一个适合当前系统环境的 ForkJoinPool

2. 提交任务

  • 将需要执行的任务提交给 ForkJoinPool,通常通过 invoke 方法或者 submit 方法来提交任务

3. 执行任务

  • ForkJoinPool 会将任务分配给其内部的 ForkJoinWorkerThread 来执行。每个工作线程都会从任务队列中获取任务并执行

4. 任务拆分与执行

  • 在任务的执行过程中,如果存在需要拆分的子任务,工作线程会调用任务的 fork 方法将子任务提交给 ForkJoinPool
  • ForkJoinPool 会根据工作窃取算法,将子任务分配给其他空闲的工作线程执行,从而实现任务的并行执行

5. 结果合并

  • 当子任务执行完成后,工作线程会调用任务的 join 方法等待子任务的执行结果
  • 如果存在必要,结果合并的过程也可以递归进行,直到得到最终的结果

Fork/Join 计算斐波那契数列

java 复制代码
// 继承 RecursiveTask 来实现可返回结果的任务
public class FibonacciTask extends RecursiveTask<Integer> {
    private int n;

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

    @Override
    protected Integer compute() {
        if (n <= 1) {
            return n;
        } else {
            FibonacciTask task1 = new FibonacciTask(n - 1);
            task1.fork(); // 拆分任务

            FibonacciTask task2 = new FibonacciTask(n - 2);
            return task2.compute() + task1.join(); // 合并结果
        }
    }

    public static void main(String[] args) {

        int n = 10;

        ForkJoinPool forkJoinPool = new ForkJoinPool();

        FibonacciTask fibonacciTask = new FibonacciTask(n);

        int result = forkJoinPool.invoke(fibonacciTask); // 同步执行任务并获取结果

        System.out.println("位于" + n + "处的斐波那契数为:" + result);

    }

}

解读:

  • 定义 FibonacciTask 类,继承自 RecursiveTask,用于计算斐波那契数列第 n 个数
  • 在 compute() 方法中,判断如果 n 小于等于 1,则返回 n
  • 否则,将任务拆分为两个部分,分表计算第 n-1 和 第 n-2 个斐波那契数
  • 通过 join() 方法等待第 n-1 的计算结果完成后将结果合并
相关推荐
\光辉岁月/4 分钟前
5.java-数组
java·开发语言
Java后端的Ai之路6 分钟前
Python进阶探索29_eval内置函数
开发语言·python·探索·eval·内置函数
谢亮_vipxieliang21 分钟前
Spring 事务失效的常见场景
java·开发语言·数据库·spring boot
时间的拾荒人34 分钟前
Qt 多线程详解:从 QThread 到实战
开发语言·qt·面试
郑州光合科技余经理43 分钟前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
2601_9620715744 分钟前
类变量和全局变量的生命周期有什么区别?
java·开发语言·jvm
code2cat1 小时前
Java进阶篇之AtomicReference:一次替换引用,读到一份完整状态
java·并发编程·不可变对象·atomicreference
专业程序开发源1 小时前
springboot简历管理系统81389-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计
Wang's Blog1 小时前
Java 项目实战: 外卖平台优化-前后端分离开发模式与工程拆分
java·开发语言
Dovis(誓平步青云)2 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑