ForkJoin 线程池

多线程系列(二十一) -ForkJoin使用详解 从 JDK 1.7 开始,引入了一种新的 Fork/Join 线程池框架,它可以把一个大任务拆成多个小任务并行执行,最后汇总执行结果。 阅读详情

一、分而治之

严格来讲,分而治之不算一种模式,而是一种思想。它可以将一个大任务拆解为若干个小任务并行执行,提高系统吞吐量。主要讲两个场景,Master-Worker 模式,ForkJoin 线程池。

ForkJoin 线程池是Jdk7之后引入的一个并行执行任务的框架。其核心思想是将任务分割为子任务,有可能子任务还是很大,还需要进一步拆解,最终得到足够小的任务。将分割出来的子任务放入双端队列中,然后几个启动线程从双端队列中获取任务执行。子任务执行的结果放到一个队列里,另起线程从队列中获取数据,合并结果。

二、ForkJoin 与传统线程池的区别

采用 “工作窃取”模式(work-stealing):当执行新的任务时,它可以将其拆分成更小的任务执行,并将小任务加到线程队列中,然后再从一个随机线程的队列中偷一个并把它放在自己的队列中。 相较于一般的线程池,ForkJoin 的优势体现在对其中包含的任务的处理方式上。在一般的线程池中,如果一个线程正在执行的任务由于某些原因无法继续运行,那么该线程会处于等待状态。而 ForkJoin,如果某个子问题由于等待另外一个子问题的完成而无法继续运行,那么处理该子问题的线程会主动寻找其他尚未运行的子问题来执行。这种方式减少了线程的等待时间,提高了性能。

三、案例

计算从 0 到 100L 的累加求和。CountTask 继承自 RecursiveTask,可以携带返回值。每次分解大任务,简单的将任务划分为 10 个等规模的小任务,并使用 fork() 提交子任务。在子任务中通过 THRESHOLD(门槛) 设置子任务分解的阈值,如果当前需要求和的总数大于 THRESHOLD,则子任务需要再次分解,如果子任务可以直接执行,则进行求和操作,返回结果。最终等待所有的子任务执行完毕,对所有结果求和。

public class CountTask extends RecursiveTask<Long> {
    //任务分解的阈值
    private static final int THRESHOLD = 11;
    private long start;
    private long end;

    public CountTask(long start, long end) {
        this.start = start;
        this.end = end;
    }

    public Long compute() {
        long sum = 0;
        boolean canCompute = (end - start) < THRESHOLD;
        if (canCompute) {
            for (long i = start; i <= end; i++) {
                sum += i;
            }
        } else {
            //分成100个小任务
            long step = (start + end) / 10;
            ArrayList<CountTask> subTasks = new ArrayList<CountTask>();
            long pos = start;
            for (int i = 0; i < 10; i++) {
                long lastOne = pos + step;
                if (lastOne > end) {
                    lastOne = end;
                }
                CountTask subTask = new CountTask(pos, lastOne);
                pos += step + 1;
                //将子任务推向线程池
                subTasks.add(subTask);
                subTask.fork();
            }

            for (CountTask task : subTasks) {
                //对结果进行join
                sum += task.join();
            }
        }
        return sum;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ForkJoinPool pool = new ForkJoinPool();
        // 累加求和 0 -> 100L
        CountTask task = new CountTask(0, 100L);
        ForkJoinTask<Long> result = pool.submit(task);
        System.out.println("sum result : " + result.get());
    }
}

ForkJoin 线程池使用一个无锁的栈来管理空闲线程,如果一个工作线程暂时取不到可用的任务,则可能被挂起。挂起的线程将被压入由线程池维护的栈中,待将来有任务可用时,再从栈中唤醒这些线程。Java8 的并行流就是基于 ForkJoin,并进行了优化。

【Java多线程】JUC之线程池(四)ForkJoin Fork/Join框架是`Java7`提供的一个用于`并行执行任务`的框架,可以把`大任务分割成若干个小任务`,`最终汇总每个小任务结果后得到大任务结果的框架`。 可以通过Fork和Join这两个单词来理解下Fork/Join框架 - **Fork**就是把一个`大任务` `切分` 为`若干子任务并行的执行` - **Join**就是`合并这些子任务的执行结果`,最后得到这个`大任务的结果`。 阅读详情

相关推荐

ForkJoinPool 线程池详解

Fork/Join 框架是一种并行计算框架,设计目的是提高具有递归性质任务的执行速度。典型的任务是将问题逐步分解成较小的任务,直到每一个子任务足够简单可以直接解决,然后再将结果聚合起来。这篇文章,我们详细地分析了 ForkJoinPool线程池,Fork/Join 是专为递归分治设计的,它充分了利用了现代多核计算能力和工作窃取算法,为某个任务的并行化提供了高效的解决方案。但是,需要特别注意,Fork/Join 更适用于 CPU 密集型任务,对于 IO 密集型任务,其表现不一定理想。

wjianwei666的专栏 942

【线程池】fork与join

1.提交给Fork/Join线程池的任务需要继承RecursiveTask(有返回值)或RecursiveAction(没有返回值)6.Fork/Join在分治的基础上加入了多线程,可以把每个任务的分解和合并交给不同的线程来完成,进一步提升运算效率。7.Fork/Join默认会创建与cpu核心数大小相同的线程池,是cpu密集型任务。4.任务拆分是将一个大型任务拆分为算法上相同的小型任务,直至不能拆分可以直接求解。1.Fork/Join是jdk1.7加入的新的线程池实现。2.体现的是一种分治思想。

王佑辉的博客 528

Win11任务栏图标消失?快速恢复指南

任务栏图标消失是Windows 11操作系统中常见的问题之一,但通过上述方法,用户通常可以轻松解决这一问题。无论是重启Windows资源管理器、使用命令提示符修复、检查系统更新和设置,还是考虑重装系统,都可以帮助用户恢复任务栏图标的正常显示。希望本文的介绍能对用户有所帮助,让Windows 11的使用更加顺畅和愉快。

mmoo_python的博客 5408

Java中常见的普通线程池与ForkJoinPool对比

线程池的介绍可以参考我的另一篇文章《Java中线程创建方式》中有提及,这里就不详细赘述,这里主要是对比普通线程与ForkJoinPool的对比。

qq_16268979的博客 9346

CVE-2025-25249漏洞深度解析:FortiOS认证绕过与实战缓解

远程代码执行(RCE)是网络安全中最危险的漏洞类型之一,其核心往往源于认证机制失效或内存安全缺陷。CVE-2025-25249正属于此类高危漏洞——它不依赖用户凭证,也不需要交互触发,而是通过超长HTTP头(如X-Forwarded-For)引发内存越界写入,直接绕过FortiOS和FortiSwitchManager的完整认证流程。该漏洞影响广泛、CVSS评分高达9.8,凸显了嵌入式设备在HTTP协议栈实现中的深层风险。在企业网络中,FortiGate等设备常作为边界守门人,一旦失陷将导致root级控制权

weixin_33694620的博客 523

手把手教你用Simulink搭建DSOGI-PLL模型(附完整代码下载)

本文详细介绍了在Simulink中搭建高鲁棒性DSOGI-PLL模型的完整工程实践指南。针对传统锁相环在非理想电网下的不足,文章深入剖析了双二阶广义积分器锁相环(DSOGI-PLL)的核心原理与优势,并提供了从模块构建、系统组装到参数整定与测试验证的全流程手把手教程,附有完整代码下载,助力工程师应对谐波、电压跌落等复杂电网工况。

weixin_29223603的博客 387

ForkJoin线程池

一、分而治之 严格来讲,分而治之不算一种模式,而是一种思想。它可以将一个大任务拆解为若干个小任务并行执行,提高系统吞吐量。主要讲两个场景,Master-Worker 模式,ForkJoin 线程池。 ForkJoin 线程池是 jdk7 之后引入的一个并行执行任务的框架,其核心思想也是将任务分割为子任务,有可能子任务还是很大,还需要进一步拆解,最终得到足够小的任务。将分割出来的子任务放入双端队列中,然后几个启动线程从双端队列中获取任务执行。子任务执行的结果放到一个队列里,另起线程从队列中获取数据,合并结果。

ChineseSoftware的博客 453

SAP固定资产原值与净值取值逻辑全解析:从数据表到ABAP实战

在企业资源计划(ERP)系统中,固定资产的价值管理是财务会计的核心模块,其关键在于准确核算资产原值与净值。从技术原理上看,这涉及对资产全生命周期业务(如购置、折旧、转移、报废)的财务建模,以及底层数据表(如ANLC、ANEP)的精准关联与计算。掌握这一逻辑的技术价值在于,能够确保财务报表数据的准确性,满足合规性要求,并为管理决策提供可靠依据。在SAP ECC或S/4HANA系统的应用场景中,ABAP开发者与财务顾问常需通过编写报表程序,从复杂的数据结构中提取资产价值信息。本文聚焦于SAP资产会计模块,深入剖

weixin_30984001的博客 389

11-线程池、forkjoin的原理分析

线程池、forkjoin的原理分析 什么是线程池 在Java中,如果每个请求到达就创建一个新线程,创建和销毁线程花费的时间和消耗的系统资源都相当大,甚至可能要比在处理实际的用户请求的时间和资源要多的多。 如果在一个JVM里面创建太多线程,可能会使系统由于过度消耗内存或”切换过度“而导致系统资源紧张。 为了解决这个问题,就有了线程池的概念,线程池的核心逻辑是提前创建好若干个线程放在一个容器中。如果有...

weixin_39169791的博客 656

【嵌入式原理系列-第七篇】ld脚本实战:从零构建MCU内存布局

本文是一篇针对嵌入式开发者的实战指南,详细讲解了如何从零开始为MCU编写ld链接器脚本以构建自定义内存布局。文章以STM32F103C8T6为例,深入剖析了MEMORY和SECTIONS指令的用法,并提供了OTA分区、非易失数据存储等高级定制案例,帮助开发者解决实际工程中的Flash与RAM管理难题,实现对程序运行的深度掌控。

weixin_29271263的博客 246

基于MATLAB的脑功能网络工具箱:BCT与FCLab

脑功能网络分析是神经科学领域的一个重要研究方向,它通过分析大脑中神经元之间的连接模式和信息传递方式,揭示脑网络的结构和功能。在这个领域,MATLAB是一个广泛使用的工具,提供了丰富的函数和工具箱来进行脑功能网络的分析和可视化。这些工具箱提供了丰富的函数和工具,使得脑功能网络的计算和分析变得更加简单和高效。在上述示例代码中,我们首先导入BCT工具箱,并构建一个邻接矩阵来表示脑网络的连接关系。在上述示例代码中,我们首先导入FCLab工具箱,并导入脑功能数据。函数对数据进行预处理,如去除噪声、降采样等操作。

web_bug407的博客 2607

ForkJoin框架以及监控线程池

​​将大任务分割为若干小任务,再将小任务得到的结果进行汇总,得到大任务结果的框架如何使用ForkJoinPoolForkJoinPool是一个采用ForkJoin框架的线程池,继承自AbstractExecutorService。

qq_62576519的博客 528

[AI8051U入门第一步]环境安装和按键控制流水灯

本文介绍了AI8051U单片机的开发环境搭建及GPIO应用。主要内容包括:1)通过ISP软件完成Keil开发环境配置;2)AI8051U特性介绍,包括32位8051内核、浮点运算单元及丰富外设;3)GPIO输入输出模式解析,并附流水灯控制代码;4)提供完整的系统初始化、延时函数及LED控制代码实现。文章配套资源包含完整工程代码,适用于智能硬件及物联网开发。

sinat_58149788的博客 669

并发编程十五:线程池任务类型和ForkJoin实战详解

文章目录线程池任务类型和ForkJoin实战详解线程池任务类型分治算法Fork/Join框架介绍Fork/Join使用Fork/Join实战案例RecursiveAction类型RecursiveTask类型CountedCompleterForkJoin原理分析ForkJoin流程图 线程池任务类型和ForkJoin实战详解 线程池任务类型 我们调整线程池中的线程数量的最主要的目的是为了充分并合理地使用CPU和内存等资源,从而最大限度地提高程序的性能。在实际工作中,我们需要根据任务类型的不同选择对应的策略

admin522043032的博客 1395

Agentic RL: 大模型后训练 SFT、PPO和GRPO

本文介绍了从LLM训练到Agentic RL的发展过程。传统LLM训练包括预训练和后训练两个阶段,其中后训练通过监督微调、奖励建模和强化学习等技术优化模型表现。针对智能体在复杂任务中的不足,提出了Agentic RL新范式,将LLM嵌入强化学习框架,通过多步交互、工具使用和环境反馈来优化长期目标。相比传统单轮对话优化(PBRFT),Agentic RL具有状态包含历史上下文、行动类型多样、动态状态转移等特点,更适合解决需要多步推理和规划的任务。这种新方法为开发更强大的智能体系统提供了可能。

Cachel Wood的博客 698

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

并发编程十三:线程池任务类型和ForkJoin实战详解

并发编程并发编程十三:线程池任务类型和ForkJoin实战详解十三:线程池任务类型和ForkJoin实战详解

huaxinzhang的博客 639

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

线程池 futuretask forkjoin 使用场景区别

在使用这些工具时,应根据具体的任务特点和需求选择合适的工具,以充分利用多核CPU的性能,提高程序的执行效率。在Java中都是用于处理并发和多线程的重要工具,但它们的使用场景和目的存在区别。

vmaps的博客 395

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

JUC——ForkJoin线程池(递归操作)

文章目录什么是ForkJoin有什么特点使用Demo 什么是ForkJoin ForkJoin 是JDK 1.7引入的一种新的线程池,其本意应该是Fork / Join。 他能将大任务拆分成小任务进行运算,最后将结果合并。其原理如下所示: 有什么特点 具有工作窃取的特点。 什么是工作窃取呢? 假设存在A和B两个线程。 当A线程执行到此处时,B线程已经执行完毕。 此时的B线程不会继续等待,会从A线程操作的双端队列中,窃取任务继续执行。 提高效率。 使用Demo 假设有这么一道需求: 计算1~10

专注写bug 978

JUC并发编程(三) --- 线程池,并行计算ForkJoin,异步回调FutureTask和CompletableFuture

文章目录10、Callable回顾11、线程池11.1 三大方法11.2 七大参数11.3 四个拒绝策略11.4 池的大小怎么确定12、并行计算ForkJoin12.1 什么是ForkJoin12.2 ForkJoin特点12.3 ForkJoinTask和ForkJoinPool实践:13、异步回调Future和FutureTask13.1 Future13.2 FutureTask13.3 CompletableFuture JUC笔记 JUC并发编程(一) — 多线程回顾,Synchronized和

化身强盗的博客 748

concurrent之线程池executorService和forkJoin用法

executorService:线程池 根据cpu核数设置线程池线程个数,编写任务类 代码如下: package com.demo; import java.util.ArrayList; import java.util.concurrent.*; import java.util.stream.LongStream; /** * @Description * @Author b...

Seven71111的博客 751

Java高并发程序设计学习笔记(六):JDK并发包(线程池的基本使用、ForkJoin)

文章目录1. 线程池的基本使用1.1. 为什么需要线程池1.2. JDK为我们提供了哪些支持 内置线程池1.2.1.1.3. 线程池的使用1.3.1. 线程池的种类1.3.2. 不同线程池的共同性 线程池构造函数详解1.4. 线程池使用的小例子1.4.1. 简单线程池1.4.2. ScheduledThreadPool2. 扩展和增强线程池...

as403045314的博客 298

2021版Java线程池教程15:什么是 ForkJoin 框架?

2021版Java线程池教程15:什么是 ForkJoin 框架? 2021版Java线程池教程15:什么是ForkJoin? 视频全集 2021版Java线程池教程 2021版Java多线程教程 代码 Github地址【全部代码】 ...

人人都是程序员官方博客 391

【JavaLearn】(13)多线程:线程生命周期、线程控制、线程同步、线程通信、线程池、ForkJoin框架

目录1. 进程和线程2. 线程的定义方式2.1 继承 Thread 类2.2 实现 Runnable 接口2.3 实现 Callable 接口3. 线程的生命周期4. 线程控制4.1 join()4.2 sleep()4.3 yield()4.4 setDaemon()4.5 interrupt()5. 线程同步5.1 问题的提出5.2 同步代码块5.2.1 同步监视器(锁子)5.2.2 执行过程5.2.3 分析5.3 同步方法5.4 Lock 锁5.4.1 使用步骤5.4.2 可重入锁5.4.3 Lock

weixin_44022996的博客 542

JUC(3):线程池+函数式接口+流式计算+ForkJoin+异步回调

11. 线程池(重点) 线程池:三大方法、7大参数、4种拒绝策略 池化技术 程序的运行,本质:占用系统的资源! 优化资源的使用!=>池化技术 线程池、连接池、内存池、对象池///..... 创建、销毁。十分浪费资源 池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我 线程池的好处: 降低资源的消耗 提高响应速度 方便管理 线程复用、可以控制最大并发数、管理线程 (1) 线程池:三大方法 //创建一个固定大小的线程池 public static ExecutorS.

qq_43378019的博客 449
上一篇: 封装了ForkJoin的并行流
下一篇: 原型模式(Prototype Pattern)
JFS_Study
博客等级 码龄6年 363粉丝 359原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JFS_Study

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值