forkjoin用法_java fork join

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


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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 进制转换(二进制、八进制、十进制、十六进制)涵盖整数与小数部分,超详细

    进制转换(二进制、八进制、十进制、十六进制)涵盖整数与小数部分,超详细今天来总结一下各种进制转换问题,详细齐全易于理解,希望对你有帮助哦!先从我们最熟悉的十进制入手吧,其他进制与十进制的转换方法都是一样的,保证能全部记住!整型有4种进制形式:1.十进制:都是以0-9这九个数字组成,不能以0开头。2.二进制:由0和1两个数字组成。3.八进制:由0-7数字组成,为了区分与其他进制的数字区别,开头都是以0开始。4.十六进制:由0-9和A-F组成。为了区分于其他数字的区别,开头都是以0x开始。先来贴一张进制转换表:一、十进制转换成二进制、八进制、十六进制

    2022年10月17日
  • cmd查看maven版本_maven获取最新版本

    cmd查看maven版本_maven获取最新版本cmd查看maven版本小技巧①键盘按下windows+Q②输入cmd③右击cmd以管理员身份运行④输入mvn-v或者mvn-version

    2022年8月22日
  • ubuntu OpenGrok的搭建

    ubuntu OpenGrok的搭建下载apache-tomcat-8.5.37和opengrok-0.12.1.5,解压。(这两个版本可以使用jdk1.7)安装sudoapt-getinstallexuberant-ctags添加环境变量#tomcat目录exportOPENGROK_TOMCAT_BASE=~/openGrok/apache-tomcat-8.5.37#修改目录,不用/var…

    2022年6月7日
  • 两个服务通过http传输excel文件

    两个服务通过http传输excel文件两个服务通过http传输excel文件

    2022年4月24日
  • qt串口通信接收数据不完整_qt串口接收数据

    qt串口通信接收数据不完整_qt串口接收数据高通QM215高速串口调试总结参考文档硬件和复用情况确认修改如下串口调试测试程序代码:将串口设置为高速串口,AP端收到的数据一直为0XFD参考文档1、sp80-pk881-6_a_qm215_linux_android_software_porting_manual.pdf2、80-pk881-21_a_qm215_linux_peripheral_(uart,_spi,_i2c)_ove…

    2022年10月10日
  • 多因子权重优化方法比较研究_权重因子是什么意思

    多因子权重优化方法比较研究_权重因子是什么意思https://www.ricequant.com/community/topic/4559在多因子量化投资体系中,具有稳定的预期收益,可解释的经济驱动理论,与其他因子的低相关性是选择alpha因子的关键指标。本篇文章中,我们以此为因子选取标准,简单地构建了自己的因子库,总共包括八个大类因子,每个大类因子中包含四到五个子类细分因子。为了比较不同的权重优化方法的优劣,本文首先采取不同的方法对各个大类…

    2022年10月6日

发表回复

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

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