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


相关推荐

  • 详解HTML超链接

    详解HTML超链接超链接是互联网提供的最令人兴奋的创新之一,它们从一开始就一直是互联网的一个特性,使互联网成为互联的网络。HTML超链接也是各个网站网页之间实现相互连接的一个手段之一,被广泛应用在各大网站。HTML超

    2022年7月4日
    34
  • jinfo介绍[通俗易懂]

    jinfo介绍[通俗易懂]1.jinfo1.1简介jinfo用于打印java的配置信息,这些配置信息包括:javasystempropertiesjvm命令行参数通过查看这些配置信息,可以了解java进程的运

    2022年8月1日
    8
  • arclistsg文档独立模型标签

    arclistsg文档独立模型标签

    2021年9月21日
    41
  • nessus8.15激活成功教程_etc怎么看激活成功了没有

    nessus8.15激活成功教程_etc怎么看激活成功了没有0x01下载NESSUS官网https://www.tenable.com/downloads/nessus离线插件all:https://plugins.nessus.org/offline

    2022年8月6日
    23
  • 学习笔记 python取余[通俗易懂]

    学习笔记 python取余[通俗易懂]python中的取余运算其实就是取模运算,所谓取模运算,就是计算两个数相除之后的余数,符号是%。如a%b就是计算a除以b的余数。用数学语言来描述,就是如果存在整数n,其中0<=|m|<|b|使得a=n*b+m,那么a%b=a‐n*b=m其中n=a/b,然后对n进行向下取整,最后得到n取模运算的两个操作数都必须是整数,可以是负整数,但是b不可以是0,因为被除数不能为0假设变量:a=10,b=20;那么b%a输出结果0…

    2022年4月25日
    64
  • qmake介绍

    qmake介绍文章目录简单介绍下qmake简要介绍关于pro文件构建一个项目使用第三方库预编译头文件让我们开始试试吧从一个简单的例子开始允许程序可以Debug添加特定平台的源文件设置当文件不存在的时候就停止qmake检查多个条件qmake可以帮助我们在跨平台构建应用程序的时候变得更简单,我们可以通过写简单的几行必要的信息来生成构建文件,我们可以在任何的软件项目中使用qmakeqmake基于pro文件生产构建…

    2022年5月19日
    87

发表回复

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

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