【揭秘】RecursiveAction全面解析

news2024/11/24 14:35:39

【揭秘】RecursiveAction全面解析 - 程序员古德

内容概要

RecursiveAction是Java中一个强大的工具,它允许将复杂任务分解为更小的子任务,这些子任务可以并行执行,从而提高整体性能,其主要优点在于能够有效地利用多核处理器,减少任务执行时间,并简化并行编程的复杂性。

核心概念

RecursiveAction 是 Java 并发包 java.util.concurrent 中的一个类,它继承自ForkJoinTask,它主要用于解决可以递归分解为更小独立任务的问题,并且这些子任务可以并行执行以优化性能,它不返回结果(与 RecursiveTask 相对,后者返回结果)。

当面对一个需要将任务分解为多个独立部分的问题时,非常合适使用 RecursiveAction ,通常它用于解决具有以下特点的问题:

  1. 可分解性:大问题可以递归地分解为更小的子问题,直到这些子问题变得足够小,可以直接解决而无需进一步分解。
  2. 无返回值:处理过程不需要聚合子任务的结果,如果需要结果,通常会使用 RecursiveTask
  3. 并行性:子任务之间相互独立,可以并行执行以提高效率。

典型的应用场景包括:

  • 并行遍历和处理数据结构:如:遍历一个大型数组或列表,并对每个元素执行某种操作,可以将数组分成几个部分,然后并行处理每个部分。
  • 分治算法:如,快速排序、归并排序等,这些算法天然地适合使用 RecursiveAction 进行并行化。
  • 图像处理:如,将大型图像分割成多个小块,并行地对每个小块进行处理。
  • 任何可并行化的批处理任务:如发送批量电子邮件、并行下载文件等。

注意:使用 RecursiveAction 的关键是正确实现 compute 方法,以定义如何分解任务和执行子任务,通过 ForkJoinPool 执行 RecursiveAction,可以自动管理任务的分解、执行和结果合并。

代码案例

如下是一个RecursiveAction的简单示例,在这个示例中,将实现一个计算数组元素之和的任务,该任务可以被递归地分解为更小的子任务。

先定义一个继承自RecursiveAction的类ArraySumAction,它计算数组的一部分元素之和,并且可以递归地分解任务,如下代码:

import java.util.concurrent.RecursiveAction;  
  
public class ArraySumAction extends RecursiveAction {  
  
    private static final int THRESHOLD = 100; // 任务分解的阈值  
    private final int[] array;  
    private final int start;  
    private final int end;  
  
    public ArraySumAction(int[] array, int start, int end) {  
        this.array = array;  
        this.start = start;  
        this.end = end;  
    }  
  
    @Override  
    protected void compute() {  
        if (end - start < THRESHOLD) {  
            // 任务足够小,直接计算  
            int sum = 0;  
            for (int i = start; i < end; i++) {  
                sum += array[i];  
            }  
            System.out.println("Sum of elements " + start + " to " + (end - 1) + " is " + sum);  
        } else {  
            // 任务太大,分解为子任务  
            int mid = start + (end - start) / 2;  
            ArraySumAction leftAction = new ArraySumAction(array, start, mid);  
            ArraySumAction rightAction = new ArraySumAction(array, mid, end);  
  
            // 递归执行子任务  
            leftAction.fork();  
            rightAction.fork();  
        }  
    }  
}

然后是client代码,并提交任务以进行计算,如下代码:

import java.util.concurrent.ForkJoinPool;  
  
public class RecursiveActionExample {  
  
    public static void main(String[] args) {  
        int[] array = new int[1000];  
  
        // 初始化数组  
        for (int i = 0; i < array.length; i++) {  
            array[i] = i;  
        }  
  
        // 创建ForkJoinPool  
        ForkJoinPool pool = new ForkJoinPool();  
  
        // 提交任务  
        pool.invoke(new ArraySumAction(array, 0, array.length));  
  
        // 注意:这里使用了invoke而不是execute,因为invoke会等待任务完成  
        // 而execute则不会。在这个例子中,希望等待所有子任务完成后再退出程序。  
  
        System.out.println("All tasks are completed.");  
  
        // 关闭ForkJoinPool(在实际应用中可能需要这样做,但在这个简单示例中不是必须的)  
        pool.shutdown();  
    }  
}

在上面的代码示例中,ArraySumAction类将数组分成两部分,直到每部分的大小小于预设的阈值(在这里是100),当任务足够小时,它将直接计算结果并打印出来,client代码创建了一个包含1000个元素的数组,并使用ForkJoinPool来执行ArraySumAction任务。

运行代码出现如下结果:

Sum of elements 0 to 99 is 4950  
Sum of elements 500 to 599 is 249500  
Sum of elements 200 to 299 is 249000  
Sum of elements 700 to 799 is 524000  
Sum of elements 400 to 499 is 499000  
Sum of elements 100 to 199 is 249500  
Sum of elements 300 to 399 is 499500  
Sum of elements 600 to 699 is 748500  
Sum of elements 800 to 899 is 1048500  
Sum of elements 900 to 999 is 1249500  
All tasks are completed.

核心总结

【揭秘】ForkJoinTask全面解析 - 程序员古德

当遇到那些可分解为更小、独立子任务的问题时,非常适合使用RecursiveAction,它通过将大任务分而治之,能显著提高处理大数据集的速度,尤其是当这些子任务之间几乎不存在通信或同步时,它的效率最高。

使用RecursiveAction的最大优势是能够充分利用多核处理器,从而加快处理速度。但是需要注意,如果子任务之间存在大量的通信或依赖,那么就不是非常适合使用RecursiveAction。

关注我,每天学习互联网编程技术 - 程序员古德

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1415613.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL注入:盲注

SQL注入系列文章&#xff1a; 初识SQL注入-CSDN博客 SQL注入&#xff1a;联合查询的三个绕过技巧-CSDN博客 SQL注入&#xff1a;报错注入-CSDN博客 目录 什么是盲注&#xff1f; 布尔盲注 手工注入 使用python脚本 使用sqlmap 时间盲注 手工注入 使用python脚本 使…

SpringBoot项目配置SSL后,WebSocket连接失败的解决方案

SpringBoot项目配置SSL后&#xff0c;WebSocket连接应使用wss协议&#xff0c;而不是ws协议。在前端配置WebSocket时&#xff0c;URL以wss://开头。

【计算机网络】中小型校园网构建与配置

拓扑图配置文件传送门 Packet Tracer-中小型校园网配置布局文件文件 相关文章 【计算机网络】IP协议及动态路由算法 【计算机网络】Socket通信编程与传输协议分析 【计算机网络】网络应用通信基本原理 原理 1. Network 广域网&#xff0c;WAN Wide Area Network&#xff…

记录浏览器能打开github.com,android studio无法拉取github项目,并且ping github.com也拼不通的问题

问题&#xff1a; Android studio编译flutter工程突然碰上如下问题&#xff1a; 在浏览器打开该地址能正常打开&#xff0c;尝试ping&#xff1a; 解决方式 通过搜索&#xff0c;查到如下办法&#xff1a; 1、首先在ipaddress.com中查询github.com域名的固定ip地址&#xff…

nginx使用stream模块代理端口

今天原本准备将本地金仓的54321端口进行代理的&#xff0c;但是发现代理后总是无法访问。后来突然发现之前使用nginx代理的是一个地址而不是端口。因此做以下笔记用来做记录。 一、stream安装与配置 假设nginx在usr/local/nginx中 1. 测试当前nginx是否有stream模块 ./usr/…

【数据结构1-1】线性表

线性表是最简单、最基本的一种数据结构&#xff0c;线性表示多个具有相同类型数据“串在一起”&#xff0c;每个元素有前驱&#xff08;前一个元素&#xff09;和后继&#xff08;后一个元素&#xff09;。根据不同的特性&#xff0c;线性表也分为数组&#xff08;vector&#…

JVM基础知识汇总篇

☆* o(≧▽≦)o *☆嗨~我是小奥&#x1f379; &#x1f4c4;&#x1f4c4;&#x1f4c4;个人博客&#xff1a;小奥的博客 &#x1f4c4;&#x1f4c4;&#x1f4c4;CSDN&#xff1a;个人CSDN &#x1f4d9;&#x1f4d9;&#x1f4d9;Github&#xff1a;传送门 &#x1f4c5;&a…

【Docker】附录二:热门镜像介绍

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; 热门镜像介绍 本章将介绍一些热门镜像的功能&#xff0c;使用方法等。包括 Ubuntu、CentOS、MySQL、MongoDB、Redis、Nginx、Wordpress、No…

k8s学习-DaemonSet和Job

1.1DaemonSet是什么 Deployment部署的副本Pod会分布在各个Node上&#xff0c;每个Node都可能运行好几个副本。DaemonSet的不同之处在于&#xff1a;每个Node上最多只能运行⼀个副本。DaemonSet的典型应用场景有&#xff1a; &#xff08;1&#xff09;在集群的每个节点上运⾏存…

Adobe ColdFusion 反序列化漏洞复现(CVE-2023-38203)

0x01 产品简介 Adobe ColdFusion是美国奥多比(Adobe)公司的一套快速应用程序开发平台。该平台包括集成开发环境和脚本语言。 0x02 漏洞概述 Adobe ColdFusion存在代码问题漏洞,该漏洞源于受到不受信任数据反序列化漏洞的影响,攻击者通过漏洞可以代码执行,可导致服务器失…

6.小时表天分区和小时分区顺序错误,怎么办?

目录 一、解决思路二、修复表结构2.1 建表2.2查询数据2.3查询数据路径2.4删表重建2.5查询表结构2.6查询数据 三、恢复数据3.1方案1 直接移动原分区数据到新分区下3.2方案2 将分区路径指导原数据路径3.3方案3 通过临时表恢复数据 一、解决思路 对于这个问题&#xff0c;主要分为…

C++类和对象——构造函数与解析函数介绍

目录 1.构造函数和析构函数 1.构造函数&#xff0c;进行初始化 2.析构函数&#xff0c;进行清理 2.构造函数的分类及调用 1.括号法 注意&#xff1a; 2.显示法 3.隐式转化法 匿名对象 3.拷贝构造函数调用时机 4.构造函数调用规则 1.定义有参构造函数&#xff0c;不…

微信小程序之页面导航、生命周期和WXS脚本

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

机器学习的数据库积累........

https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf1_detection_zoo.md ​​​​​​​ 另一个database:&#xff08;网址:Object Detection Made Easy with TensorFlow Hub: Tutorial&#xff09; Object Detection Made Easy with Ten…

【Java Kubernates】Java调用kubernates提交Yaml到SparkOperator

背景 目前查询框架使用的是trino&#xff0c;但是trino也有其局限性&#xff0c;需要准备一个备用的查询框架。考虑使用spark&#xff0c;spark operator也已经部署到k8s&#xff0c;现在需要定向提交spark sql到k8s的sparkoperator上&#xff0c;使用k8s资源执行sql。 对比 …

RCC——使用HSE/HSI配置时钟

RCC 文章目录 前言一、背景二、仿真计算周期 2.1 2.2 三、MCO引脚输出时钟总结 前言 前期疑问&#xff1a;1、RCC是什么意思。 2、最终配好的72M是系统时钟吗&#xff1f; 3、一共有哪些时钟 本文目标&#xff1a;将PLL时钟配置成72M 疑问解答&#xff1a;最终配好的时钟是…

GitLab16.8配置webhooks、Jenkins2.4配置GitLab插件实现持续集成

看本篇文章的前提是已经部署完GItlab和Jenkins服务器&#xff0c;已经可以手动构建成功&#xff0c;并且经过了很多次实践&#xff0c;对这两款软件基本熟悉。 希望大家都能够厚积薄发。 ~~~道理都懂&#xff0c;但有时候做不到&#xff0c;所以还是没真正懂。 前端自动化&am…

【Qt无门槛入门】信号以及信号机制及其常用控件(1)

信号与信号槽 信号源&#xff1a;由哪个控件发出的信号。 信号的类型&#xff1a;用户进行不同的操作&#xff0c;就可能出发不同的信号。 信号处理的方式:槽&#xff08;slot&#xff09;某个对象接收到这个信号之后&#xff0c;就会做一些相关的处理动作。但是Qt对象不会无故…

uniCloud 免费版和商用版

概述 uniCloud为每个开发者提供一个免费的服务空间&#xff0c;更低门槛按量付费是serverless的特色&#xff0c;如果没有消耗硬件资源&#xff0c;就完全不用付款serverless比传统的云主机更便宜传统云主机一旦被攻击&#xff0c;高防价格非常昂贵。而uniCloud无需支付高防费…

零基础学习数学建模——(五)美赛写作指导

本篇博客将详细讲解美赛论文写作。 文章目录 标题摘要目录引言问题背景问题重述前人研究我们的工作 模型假设及符号说明正文问题分析模型建立模型求解结果分析模型检验 模型优缺点及展望模型优缺点模型展望 参考文献及附录参考文献附录 2024年美赛论文新要求 标题 标题要简洁…