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:用于没有返回结果的任务。

完整代码

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 欧式距离计算公式

    欧式距离计算公式欧式距离也称欧几里得距离,是最常见的距离度量,衡量的是多维空间中两个点之间的绝对距离。也可以理解为:m维空间中两个点之间的真实距离,或者向量的自然长度(即该点到原点的距离)。在二维和三维空间中的欧氏距离就是两点之间的实际距离下面是具体的计算公式…

  • 10月30日 迅雷白金会员vip账号分享「建议收藏」

    10月30日 迅雷白金会员vip账号分享「建议收藏」www.91freevip,就要免费VIP网10月30日8:53更新迅雷会员VIP账号:迅雷vip账号894273128:1密码3579791迅雷vip账号juhao11:2密码19577

  • Android preference_android:orientation=”vertical”

    Android preference_android:orientation=”vertical”【正文】一、PreferenceFragment的引入:PreferenceActivity是一个非常有用的基类,当我们开发Android项目时避免不了选项设置,这些设置习惯用Preference来保存。Android专门为这种Activity提供了便捷的基类PreferenceActivity。如果继承自Preference则不需要自己控制Preference的读写,Preference

  • 网页批量更新快照软件-百度快照更新优化[通俗易懂]

    网页批量更新快照软件-百度快照更新优化[通俗易懂]百度快照优化,什么是百度快照?当网站被收录后百度会存有一份存文本的备份,称之为百度快照。但百度只会保留文本信息,不会保留图片、音乐、视频、等非文本的信息。而堡垒快照页面也是从原有收录页面调用的,如果原有收录页面打不开。那么快照片上的非文本的信息内容将会无法得到显示。那么我们怎么做好百度快照优化呢。首先在更新百度快照之前,网站有一定的更新。百度快照更新的好处就是更新了你网站的排名。进一步地了解网站的一个动态。百度快照分为:自动更新快照和手动更新快照自动更新快照,就是等待百度主动更新你.

  • stm32f103可以驱动摄像头吗?_stm32f103c8t6手册

    stm32f103可以驱动摄像头吗?_stm32f103c8t6手册最近,由于想要做摄像头巡线小车,所以就花了两个星期的时间写了一个OV7725的摄像头驱动。主要器材:鹰眼OV7725摄像头、stm32f103vet6、LCD液晶屏(ILI9341)在这里我不讲解OV7725的工作原理(传输时序、寄存器配置),但是关键还是在OV7725上,详细讲解网上有很多,也可以参考下这篇博客https://www.cnblogs.com/raymon-tec/cate…

  • Prometheus时序数据库

    Prometheus时序数据库Prometheus时序数据库 一、Prometheus1、Prometheus安装1)源码安装prometheus安装包最新版本下载地址:https://prometheus.io/download/wgethttps://github.com/prometheus/prometheus/releases/download/v2.3.2/prometheus-2….

发表回复

您的电子邮箱地址不会被公开。

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