forkjoin用法_java fork join

forkjoin用法_java fork join目录前言前言ForkJoin是JDK1.7加入的多线程并行处理框架。ForkJoin使用`分而治之`的思想,把一个大任务拆分成一个个小任务,然后再聚合,得到最终结果。这有点像Hadoop中的MapReduce。还支持工作窃取。

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

前言

  • ForkJoin是JDK1.7加入的多线程并行处理框架。ForkJoin使用分而治之的思想,把一个大任务拆分成一个个小任务,然后再聚合,得到最终结果。这有点像Hadoop中的MapReduce。还支持工作窃取。
  • 下面附上ForkJoin Java并发动画。

这个Jar包下载地址: https://sourceforge.net/projects/javaconcurrenta/files/,还有很多有意思的动画,帮助我们学习JUC。

在这里插入图片描述

什么是工作窃取:假设有A、B两个线程执行一个任务,A比较快,把活儿干完了,这时候A可以把B的一部分活接过来。这样总体来说会加快任务执行速度。

应用

需求

  • 假设有这样一个需求:我要统计用户表里全部的金额。这个表里有17000003条数据。如果我直接用SQL统计很慢,如下图所示。
    在这里插入图片描述
  • 花费了4.563秒才查出来。
  • 我发现每次1000000条还是很快的,如下图所示。
    在这里插入图片描述
  • 我就想是否可以写个程序,拆分成多个小任务,分批查询,然后合并结果。

使用

根据id范围查询求SUM

...省略...
 @Override
    public long sumRecord(int toId, int fromId) {
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        // 用in语句合并成一条SQL,避免多次请求数据库的IO
        queryWrapper.ge("id", fromId);
        queryWrapper.le("id", toId);
        queryWrapper.select("IFNULL(SUM(money),0) as money");
        List<Users> users = usersMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(users)) {
            return users.get(0).getMoney();
        }
        return 0;
    }
...省略...

创建任务类和测试用例

 ...省略...

    @Test
    public void sumTask() {
        long startTime = System.currentTimeMillis();
        ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors() * 2);
        // 模拟千万数据
        int min = 1;
        int max = 17000003;
        SumTask sumTask = new SumTask(min, max, userService);
        pool.invoke(sumTask);

        System.out.println("总数 " + sumTask.join() +
                " 执行时间 " + (System.currentTimeMillis() - startTime));

    }

    public static final Integer THRESHOLD = 1000000;

    public static class SumTask extends RecursiveTask<Long> {

        int fromId;
        int toId;
        private UserService userService;


        public SumTask(int fromId, int toId, UserService userService) {
            this.fromId = fromId;
            this.toId = toId;
            this.userService = userService;
        }

        @Override
        protected Long compute() {
            if (toId - fromId < THRESHOLD) {
                return sumRecord(toId, fromId);
            } else {
                int mid = (fromId + toId) / 2;
                SumTask left = new SumTask(fromId, mid, userService);
                SumTask right = new SumTask(mid + 1, toId, userService);
                invokeAll(left, right);
                return left.join() + right.join();
            }
        }

        public Long sumRecord(int toId, int fromId) {
            System.out.println(" 参数 " + fromId + " " + toId);
            return userService.sumRecord(toId, fromId);
        }


    }
...省略...

执行结果

  • 执行结果明显速度快了。
    在这里插入图片描述

小结

  • 我们可以在new ForkJoinPool(int parallelism)传入线程数(默认是CPU核心数),进行调优。
  • 如果是继承RecursiveAction:用于没有返回结果的任务。

完整代码

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/191276.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • bootefi分多大合适_boot from network

    bootefi分多大合适_boot from network转载:http://blog.csdn.net/olei_oleitao/article/details/7919307 一、DM36X的BOOT过程介绍DM36x的BOOT过程和DM6446、DM6467完全是一样的,因为都是ARM926EJS架构,里边都有一个RBL,这RBL在芯片出厂的时候都烧写在ROM里,芯片上电复位后RBL在运行,然后读取BOOTMODE引脚的电平状态,决定

    2022年8月13日
    5
  • mysql中update和select结合使用

    mysql中update和select结合使用

    2022年2月20日
    67
  • 如何激活成功教程SQLyog 企业版,无限期试用[通俗易懂]

    如何激活成功教程SQLyog 企业版,无限期试用[通俗易懂]如何激活成功教程SQLyog企业版,无限期试用SQLyog是一个功能强大,界面简洁大方的MysqlGUI客户端。截止到这篇博客日期2009-08-15,sqlyog8.13已经释出。其通用版是免费的版本——已经是同类软件的佼佼者了但其打开、关闭软件提示画面,软件界面里灰色的不可用企业功能这是让人心里痒痒!网上也有不少的激活成功教程版,先不管其是否真的完美激活成功教程,这使用激活成功教程的软件总是叫人底气

    2022年9月23日
    2
  • 国内CMS技术发展的外在表现形式「建议收藏」

    国内CMS技术发展的外在表现形式「建议收藏」网站作为企事业单位的网上名片已经成为必需。大多数单位都选择利用成熟的CMS(内容管理系统)交给专业的公司或者本单位负责人(相当于站长)建设自己的网站。国内CMS技术的不断发展的外在表现,以便站长和建站公司选择合适的CMS系统建设更强大的网站。我建站时用过很多CMS系统,各有各的特点。现在之所以选择主要用We7的CMS是觉得在以下方面还是不错的。一产品成熟度。据我了解We7CMS系统

    2022年5月18日
    35
  • maven 打的包在哪_maven打包流程学习「建议收藏」

    maven 打的包在哪_maven打包流程学习「建议收藏」前言:最近工作中遇到了几次跟maven打包相关的问题,每个问题上网查资料解决都花了不少时间,很影响工作进度。既然遇到好几次,每次都能发现知识盲点,干脆总结整理一下,啃掉这个难啃的骨头。ps:最近看到了一个很有意思句子:因为今天不想跑步,所以才去跑,这是长距离跑者的思维方式。转载:正文:还是首先描述一下最近遇到的几个问题吧:一、初见springboot多模块项目mvn打包遇到的问题-存在依赖但却…

    2022年5月11日
    42
  • hibernate与mybatis区别对比

    hibernate与mybatis区别对比hibernate和mybatis区别对比

    2025年7月11日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号