JAVA使用线程池查询大批量数据

2023-11-19

前言

在开发过程中可能会碰到某些独特的业务,比如查询全部表数据,数据量过多会导致查询变得十分缓慢。虽然在大多数情况下并不需要查询所有的数据,而是通过分页或缓存的形式去减少或者避免这个问题,但是仍然存在需要这样的场景,比如需要导出所有的数据到excel中,导出数据之前,肯定需要先查询表中数据,这个查询的过程中数据量一旦过大,单线程查询数据会严重影响程序性能,有可能过长的查询时间导致服务宕机。现在模拟使用多线程来查询一张数据量较大的表。


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是线程,什么是线程池

这一块内容就不再做过多的赘述,本文章只是直接使用案例来使用它们。不太了解的可自行百度查一下。

二、使用步骤

  1. 查询出表的数据总量。
  2. 数据的切分,根据本机CPU的核数配置合适数量的线程处理数,根据数据总量为不同的线程分配不同的查询数据量分段,即不同的线程查询不同分段的数据。
  3. 将各个查询数据的线程提交至线程池,这里使用的线程是带有返回结果的异步线程。(这样能把所有查询结果合并,才能进行下一步的操作。拿不到处理后的数据还怎么做下一步操作呢,所以一点要选择带有返回结果的线程)

controller层:

    @GetMapping("/getAllData")
    @ApiOperation(value = "多线程获取日志数据",)
    public class MultiThreadController {

    @Autowired
    private ThredService thredService;

    @GetMapping("/testThredData")
    public List testThredData(){
        return thredService.getAllResult();
    }
}

service层:

  public interface ThredService {

    public List getAllResult();

}

serviceImpl层:

@Service
public class  ThredServiceImpl implements ThredService {

    @Autowired
    private MultiThreadQueryUtil multiThreadQueryUtil;

    @Override
    public List getMultiCombineResult() {
        return multiThreadQueryUtil.getMultiCombineResult();
    }

}

多线程实现类(核心)

@Service
public class MultiThreadQueryUtil {

    @Autowired
    private WorkflowTaskMapper workflowTaskMapper;

    /**
     * 获取多线程结果并进行结果合并
     * @return
     */
    public List<List> getMultiCombineResult() {
        //开始时间
        long start = System.currentTimeMillis();
        //返回结果
        List<List> result = new ArrayList<>();
        //查询数据库总数量
        int count = workflowTaskMapper.selectCountAll();
        Map<String,String> splitMap = ExcelLocalUtils.getSplitMap(count,5);
        int bindex = 1;
        //Callable用于产生结果
        List<Callable<List>> tasks = new ArrayList<>();
        for (int i = 1; i <= 5; i++) {
            //不同的线程用户处理不同分段的数据量,这样就达到了平均分摊查询数据的压力
            String[] nums = splitMap.get(String.valueOf(i)).split(":");
            int startNum = Integer.valueOf(nums[0]);
            int endNum = Integer.valueOf(nums[1]);
            Callable<List> qfe = new ThredQuery(startNum, endNum-startNum+1);
            tasks.add(qfe);
            bindex += bindex;
        }
        try{
            //定义固定长度的线程池  防止线程过多,5就够用了
            ExecutorService executorService = Executors.newFixedThreadPool(5);
            //Future用于获取结果
            List<Future<List>> futures=executorService.invokeAll(tasks);
            //处理线程返回结果
            if(futures!=null&&futures.size() > 0){
                for (Future<List> future:futures){
                    result.addAll(future.get());
                }
            }
            //关闭线程池,一定不能忘记
            executorService.shutdown();
        }catch (Exception e){
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("线程查询数据用时:"+(end-start)+"ms");
        return result;
    }

}

不同的线程负责查询自己线程负责的数据分段的数据方法
也就是你的业务处理方法:

public class ThredQuery implements Callable<List> {

    public static SpringContextUtil springContextUtil = new SpringContextUtil();

    private int start;

    private int end;

    //每个线程查询出来的数据集合
    private List datas;

    public  ThredQuery(int start,int end) {
        this.start=start;
        this.end=end;
        //每个线程查询出来的数据集合
        QueryService queryService= springContextUtil.getBean("queryService");
        List count = queryService.getQueryData(start,end);
        datas = count;
    }

    //返回数据给Future
    @Override
    public List call() throws Exception {
        return datas;
    }

}

总结

商品表大概7万多条数据,测试了几次,平均下来,不到3秒的时间,如果不这样写,单线程查询出来的数据大概是9s左右。

源码:

点击此处跳转源码地址

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVA使用线程池查询大批量数据 的相关文章

随机推荐

  • 多个js文件调用函数问题

    多个js文件调用函数问题 最近在做一个项目 用的 jquery 和 easyui 有很多常用的函数我就把它们写到了common js里面 然后又写了一link jsp 把常用的css和js文件都写在里面 然后页面直接include 写着写着
  • 蒸馏神经网络(Distill the Knowledge in a Neural Network)

    本文是阅读Hinton 大神在2014年NIPS上一篇论文 蒸馏神经网络的笔记 特此说明 此文读起来很抽象 大篇的论述 鲜有公式和图表 但是鉴于和我的研究方向 神经网络的压缩十分相关 因此决定花气力好好理解一下 1 Introduction
  • vuepress-yarn-nodes-静态网页_个人博客搭建

    nodes官网 https nodejs org en 先下载nodes进行安装 一般nodes会自带包管理器npm 注意npm与nodes的对应关系 除了npm之外还有yarn包管理器 一般会用npm安装这个包 npm install g
  • esp32cam门禁系统简易教程

    esp32cam门禁系统简易教程 人脸识别 1 环境安装 最好有梯子 arduino IDE 1 官网下载地址 选择相应版本下载Windows ZIP file 无脑安装 2 配置IDE 打开IDE 文件 gt 首选项 gt 附加开发板管理
  • Android属性动画

    http bbs itheima com thread 172632 1 1 html 什么是Android属性动画 属性动画 Property Animation 系统是一个健壮的动画框架系统 它可以满足你大部分动画需求 不管动画对象是否
  • Spring Boot 使用及启动源码解析一

    前言 本篇文章会介绍Spring Boot 的基本原理 以及以及一些使用 常见的配置方式等 如何从单一架构延申到现在的前后端分离 垂直应用架构 的项目 从网站流量很小到现在的网站流量动则几百万上下的 发展 加速前端的架构 到后面 的分布式服
  • [QT编程系列-25]:多线程机制 - QThread和MoveToThread简介

    目录 第1章 简介 1 1 多线程的目的 1 2 QThread多线程使用方法 1 3 QT支持多线的步骤 第2章 QThread 2 1 概述 2 2 moveToThread 第1章 简介 1 1 多线程的目的 QThread类提供了一
  • deepin访问不了网页

    deepin15 解决访问不了网页 IP能ping通 页面访问不了 IP能ping通 ping域名失败 是下边这个情况 执行成功 ping 202 108 22 5 baidu的ip 执行失败 ping www baidu com 是因为浏
  • ElementUi常用组件创建前端页面

    elementui 创建前端页面
  • Qt小项目2 图片查看器

    头文件 ifndef WIDGET H define WIDGET H include
  • Shell脚本概述、简单Shell脚本的编写

    一 shell概述 shell是一个命令行解释器 它接收应用程序 用户命令 然后调用操作系统内核 shell还是一个强大的编程语言 易编写 易调试 灵活性强 二 shell解析器 1 Linux提供的shell解析器有 root CS YT
  • 大起大落,蚂蚁上市被叫停,蚂蚁的程序员们怎么样了?

    继马云被有关部门联合约谈以后 万众瞩目的蚂蚁上市被叫停了 一石激起千层浪 这个爆炸性的新闻引起了人们的热议 来看看大家都说了些什么 首先表达一下对蚂蚁金服员工的深切同情 毕竟之前大家都以为马上就能实现财务自由 走上人生巅峰 结果来了这么一出
  • 机器学习-Day04

    在处理包含字符串的数据时使用pandas 常用的数据类型 1 series一维 带标签数组 2 dataframe二维 Series容器 1 pandas索引 import pandas as pd t pd Series 1 21 31
  • Android Studio的build.gradle里面的各种版本信息

    Android studio 是采用 Gradle 来构建项目 Gradle 是一个非常先进的项目构建工具 我们在导入Android项目后 只要项目同步成功 就会出现以下文件夹 如图是build gradle Module app 文件的代
  • python3字符串与二进制互相转换

    人闲太久 努力一下就以为是在拼命 一 前言 python中 没有 0 1 形式的二进制类型 但我们依然可以存储二进制类型的数据 利用字符串 string 类型 可以存储二进制数据 即 将二进制数据以字符串的形式存储 下面分享一种字符串和二进
  • IDEA——》安装Scala插件

    推荐链接 总结 Java 总结 Mysql 总结 Redis 总结 Kafka 总结 Spring 总结 SpringBoot 总结 MyBatis MyBatis Plus 总结 Linux 总结 MongoDB 总结 Elasticse
  • Hive基本使用(5)

    三 排序 1 Order By 全局排序 只有一个Reducer ASC ascend 升序 默认 DESC descend 降序 b ORDER BY 子句在SELECT语句的结尾 demo1 按照工资升序 hive dyhtest gt
  • 动态中位数(对顶堆)

    上面是一个小根堆 下面是一个大根堆 维护两个性质 1 小根堆元素 gt 大根堆元素2 大根堆元素个数比小根堆元素个数多1 结果出堆大根堆top即可 include
  • 网站降权的康复办法(详解百度SEO数据分析)

    随着搜索引擎算法的不断升级 很多网站在SEO优化过程中遭遇到降权的情况 如果您的网站也遭遇到了类似的问题 不必惊慌失措 本文将为您详细介绍网站降权恢复的方法 包括百度SEO数据分析 网站收录少的5个原因 网站被降权的6个因素以及百度SEO提
  • JAVA使用线程池查询大批量数据

    前言 在开发过程中可能会碰到某些独特的业务 比如查询全部表数据 数据量过多会导致查询变得十分缓慢 虽然在大多数情况下并不需要查询所有的数据 而是通过分页或缓存的形式去减少或者避免这个问题 但是仍然存在需要这样的场景 比如需要导出所有的数据到