SpringBoot多线程查询实战-查询库中所有数据多线程实现

文章目录

    • 案例说明
    • 测试结论
    • Controller层核心代码
    • 测试数据生成
    • 测试报告
    • 源码获取

案例说明

本案例我们希望使用三种方式查询数据库某张表下所有数据:

  • 单线程+分页查询获取所有数据
  • 单线程+直接查询获取所有数据
  • 多线程+分页查询获取所有数据

测试结论

​ ​ ​在比较这三种方式的效率时,我们需要考虑几个关键因素:数据量的大小、查询操作的复杂性、以及并行处理的能力。

​ 首先,我们来看 list() 方法。这个方法直接调用 deviceTestOneService.list() 来获取表中的所有数据。如果数据量非常大,那么这种方法可能会导致内存溢出,因为它会一次性加载所有数据到内存中。此外,由于它是同步执行的,没有利用并行处理的能力,所以在处理大量数据时可能会比较慢。

​ ​ 接下来是 getPageAll() 方法。这个方法采用了分页查询的方式,每次只获取一部分数据,从而避免了内存溢出的问题。然而,它也是同步执行的,没有利用多线程或并行处理的能力。如果每次分页查询的数据量仍然很大,或者需要查询的轮数很多,那么这种方法的效率可能仍然会受到限制。

​​ ​ 最后是 multithreading() 方法。这个方法利用了多线程并行处理的能力,将查询任务分配给多个线程同时执行。这样,可以同时从数据库中获取多个数据块,从而提高了整体的查询效率。当然,多线程也带来了一定的复杂性和开销,比如线程创建、管理和同步等。但是,在数据量较大且服务器资源足够的情况下,多线程方法通常能够显著提高查询效率。

​ ​ 综上所述,从效率角度来看,我们可以将这三种方式按以下顺序排序(从高到低)

  • multithreading():利用多线程并行处理,能够同时执行多个查询任务,提高了整体的查询效率。
  • getPageAll():采用分页查询的方式,避免了内存溢出的问题,但仍然是同步执行的。
  • list():直接加载所有数据到内存中,可能导致内存溢出,且没有利用并行处理的能力,效率较低。
    ​​ ​ 需要注意的是,这个排序是基于一般情况下的假设。在实际应用中,效率还受到其他因素的影响,如数据库的性能、网络延迟、服务器资源等。因此,在选择使用哪种方式时,还需要根据具体的场景和需求进行评估和测试。

Controller层核心代码

package com.interviewbar.system.controller;import com.interviewbar.common.vo.Result;
import com.interviewbar.system.entity.DeviceTestOne;
import com.interviewbar.system.service.DeviceTestOneService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;/*** @author FangGL*/
@RestController
@RequestMapping("/deviceTestOne")
public class DeviceTestOneController {private final DeviceTestOneService deviceTestOneService;public DeviceTestOneController(DeviceTestOneService deviceTestOneService) {this.deviceTestOneService = deviceTestOneService;}/*** 查询表中所有数据* @return*/@GetMapping("/list")public Result list() {List<DeviceTestOne> list = deviceTestOneService.list();return Result.success(list);}/*** 查询表中所有数据* @return*/@GetMapping("/getPageAll")public Result getPageAll() {List<DeviceTestOne> list = new ArrayList<>();int limit = 50000;long count = deviceTestOneService.count();//循环次数long cycles = count / limit+1;for (int i = 0; i < cycles; i++) {long startIdx = i * limit;long endIdx = (i + 1) * limit;if (endIdx > count){endIdx = count;}List<DeviceTestOne> list1 = deviceTestOneService.getPageAll(startIdx, endIdx);list.addAll(list1);}return Result.success(list);}@GetMapping("/multithreading")public Result multithreading() {List<DeviceTestOne> list = new ArrayList<>();int limit = 50000;long count = deviceTestOneService.count();//循环次数long cycles = count / limit+1;CountDownLatch latch = new CountDownLatch(7);ExecutorService executorService = Executors.newFixedThreadPool(7);for (int i = 0; i < 7; i++) {final int currentIndex = i;executorService.submit(() -> {long startIdx = currentIndex * limit;long endIdx = (currentIndex + 1) * limit;if (endIdx > count) {endIdx = count;}List<DeviceTestOne> list1 = deviceTestOneService.getPageAll(startIdx, endIdx);list.addAll(list1);latch.countDown(); // 通知完成});}try {// 等待所有任务完成latch.await();// 没有异常发生,开始关闭线程池executorService.shutdown();// 等待线程池关闭完成,或者达到超时时间if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {// 如果超时,强制关闭线程池executorService.shutdownNow();}} catch (InterruptedException e) {// 发生中断异常,重新设置中断状态Thread.currentThread().interrupt();// 尝试关闭线程池executorService.shutdownNow();}return Result.success(list);}
}

测试数据生成

建表语句

CREATE TABLE `x_device_test_one` (`line_id` varchar(255) DEFAULT NULL,`device_id` varchar(255) DEFAULT NULL,`date_partition` varchar(255) DEFAULT NULL,`status` varchar(255) DEFAULT NULL,`card_swipes_count` bigint(20) DEFAULT NULL,`station_id` int(11) DEFAULT NULL,`id` int(255) NOT NULL AUTO_INCREMENT,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=340004 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
数据生成根据自己需求生成适合数据量即可第一步:运行下面语句
DELIMITER  //
CREATE PROCEDURE InsertTestData()  
BEGIN  DECLARE i INT DEFAULT 0;  WHILE i < 300000 DO  INSERT INTO x_device_test_one (line_id, device_id, date_partition, status, card_swipes_count, station_id)  VALUES (  CONCAT('line_', FLOOR(RAND() * 1000000)), -- 假设line_id是一个随机生成的字符串  CONCAT('device_', FLOOR(RAND() * 1000000)), -- 假设device_id是一个随机生成的字符串  DATE_FORMAT(NOW() - INTERVAL FLOOR(RAND() * 3650) DAY, '%Y-%m-%d'), -- 假设date_partition是过去3650天内的随机日期  CONCAT('status_', FLOOR(RAND() * 5) + 1), -- 假设有5种状态,编号从1到5  FLOOR(RAND() * 10000), -- 假设card_swipes_count是一个0到9999之间的随机数  FLOOR(RAND() * 1000) -- 假设station_id是一个0到999之间的随机数  );  SET i = i + 1;  END WHILE;  
END //
DELIMITER ;  第二步:运行下面语句
-- 调用存储过程以插入数据  
CALL InsertTestData();  注意:如果你不再需要它,才执行这一条
-- 删除存储过程
DROP PROCEDURE IF EXISTS InsertTestData;

测试报告

单线程+分页查询获取所有数据-测试报告
平均耗时4.15秒

在这里插入图片描述

单线程+直接查询获取所有数据-测试报告
平均耗时3.14秒

虽然单线程直接查询库中所有数据要比单线程分页快,但是存在极大风险。
在这里插入图片描述

多线程+分页查询获取所有数据-测试报告
平均耗时1秒

在这里插入图片描述

参考文档:https://www.cnblogs.com/iamamg97/p/15579233.html

源码获取

在笔者的代码仓库中已存放本次测试的代码及数据库,欢迎下载并start🤖
https://gitee.com/fanggaolei/multithreading-project

参考文档:https://www.cnblogs.com/iamamg97/p/15579233.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/775061.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3D数据格式导出工具HOOPS Publish如何生成高质量3D PDF?

在当今数字化时代&#xff0c;从建筑设计到制造业&#xff0c;从医学领域到电子游戏开发&#xff0c;3D技术已经成为了不可或缺的一部分。在这个进程中&#xff0c;将3D模型导出为3D PDF格式具有重要的意义。同时&#xff0c;HOOPS Publish作为一个领先的解决方案&#xff0c;为…

通过Jmeter准备压测数据-mysql示例

1、新建线程组 总共30万条数据 2、创建jdbc链接 创建jdbc连接配置 配置mysql连接 需要在jmeter安装的路径\apache-jmeter-5.6.3\lib\ext 目录下添加mysql 驱动 3、创建jdbc请求 jdbc链接名称需要与上一步中的保持一致&#xff0c;同时添加insert语句 例如 INSERT INTO test…

iOS - Runtime-消息机制-objc_msgSend()

iOS - Runtime-消息机制-objc_msgSend() 前言 本章主要介绍消息机制-objc_msgSend的执行流程&#xff0c;分为消息发送、动态方法解析、消息转发三个阶段&#xff0c;每个阶段可以做什么。还介绍了super的本质是什么&#xff0c;如何调用的 1. objc_msgSend执行流程 OC中的…

阿里云实时计算Flink的产品化思考与实践【上】

摘要&#xff1a;本文整理自阿里云高级产品专家黄鹏程和阿里云技术专家陈婧敏在 FFA 2023 平台建设专场中的分享。内容主要为以下五部分&#xff1a; 阿里云实时计算 Flink 简介产品化思考产品化实践SQL 产品化思考及实践展望 该主题由黄鹏程和陈婧敏共同完成&#xff0c;前半程…

java调用jacob进行文件转换ppt转pdf或者png

java调用jacob进行文件转换ppt转pdf或者png 前情提要 最近项目上&#xff0c;遇到一个复杂的ppt&#xff0c;最终要求是要将ppt每一页转成图片原本这个是不难&#xff0c;网上一搜一大堆案例&#xff0c;外加我本身也比较精通aspose&#xff0c;那还不是分分钟搞定。结果就是…

Django 中间件

【一】Django框架之生命周期流程图 【二】介绍 【1】概述 Django 中的中间件&#xff08;Middleware&#xff09;是一个轻量级、底层的“插件”系统&#xff0c;用来全局地改变 Django 的输入或输出。每个中间件组件负责处理特定的全局任务&#xff0c;例如处理会话、处理跨站…

【有限状态机】- FSM详细讲解 【附Autoware有限状态机模型代码讲解】

参考博客&#xff1a; &#xff08;1&#xff09;FSM&#xff08;有限状态机&#xff09; &#xff08;2&#xff09;关于有限状态机(FSM)的一些思考 &#xff08;3&#xff09;状态设计模式 1 状态机简介 有限状态机FSM&#xff1a;有限个状态以及在这些状态之间的转移和动作…

2024年最新最全Vue3开源后台管理系统复盘总结

在现代前端开发中&#xff0c;搭建一个高效、灵活、易用的后台管理系统并不容易。然而&#xff0c;Vue3 的出现为我们提供了一个备受瞩目的选择。作为一个现代化的前端框架&#xff0c;Vue3 具有众多优点&#xff0c;能够帮助开发者快速搭建企业级中后台产品原型。 今天&#…

iphoneX系统的参数

1. 2. 3. 4. 5.相关的网址信息 Apple iPhone X 規格、价格和评论 | Kalvo Apple iPhone X 規格、价格和评论 | Kalvo

UOS、Linux下的redis的详细部署流程(适用于内网)

提示&#xff1a;适用于Linux以及UOS等内外网系统服务器部署。 文章目录 一.上传离线包二.部署基本环境三.解压并安装redis四.后台运行redis五.uos系统可能遇到的问题六.总结 一.上传离线包 1.自己去Redis官网下载适配自己部署系统的redis安装包。 2.通过文件传输工具&#xf…

Rust使用原始字符串字面量实现Regex双引号嵌套双引号正则匹配

rust使用Regex实现正则匹配的时候&#xff0c;如果想实现匹配双引号&#xff0c;就需要使用原始字符串字面量&#xff0c;不然无法使用双引号嵌套的。r#"..."# 就表示原始字符串字面量。 比如使用双引号匹配&#xff1a; use regex::Regex;fn main() {println!(&qu…

快速幂算法在Java中的应用

引言&#xff1a; 在计算机科学和算法领域中&#xff0c;快速幂算法是一种用于高效计算幂运算的技术。在实际编程中&#xff0c;特别是在处理大数幂运算时&#xff0c;快速幂算法能够显著提高计算效率。本文将介绍如何在Java中实现快速幂算法&#xff0c;并给出一些示例代码和应…

151 shell编程,正则表达式,在C语言中如何使用正则表达式

零&#xff0c;坑点记录&#xff1a;bash 和 dash 的区别&#xff0c;导致的坑点 查看当前用的shell 是啥&#xff0c;用的是/bin/bash hunandedehunandede-virtual-machine:~$ echo $SHELL /bin/bash 当shell 脚本运行的时候&#xff08;后面会学到方法&#xff0c;这里是最…

全局UI方法-弹窗一警告弹窗(AlertDialog)

1、描述 显示警告弹窗组件&#xff0c;可设置文本内容与响应回调。 2、属性 名称参数类型参数描述showAlertDialogParamWithConfirm | AlertDialogParamWithButtons定义并显示AlertDialog组件。 2.1、AlertDialogParamWithConfirm对象说明&#xff1a; 参数名称参数类型必填…

『Apisix安全篇』探索Apache APISIX身份认证插件:从基础到实战

&#x1f680;『Apisix系列文章』探索新一代微服务体系下的API管理新范式与最佳实践 【点击此跳转】 &#x1f4e3;读完这篇文章里你能收获到 &#x1f6e0;️ 了解APISIX身份认证的重要性和基本概念&#xff0c;以及如何在微服务架构中实施API安全。&#x1f511; 学习如何使…

FreeRTOS(三)

第二部分 事件组 一、事件组的简介 1、事件 事件是一种实现任务间通信的机制&#xff0c;主要用于实现多任务间的同步&#xff0c;但事件通信只能是事件类型的通信&#xff0c;无数据传输。其实事件组的本质就是一个整数(16/32位)。可以是一个事件发生唤醒一个任务&#xff…

ClickHouse初体验

1.clickHouse是啥&#xff1f; ClickHouse 是俄罗斯的 Yandex 于 2016 年开源的列式存储数据库(DBMS)&#xff0c;使用 C语言编写&#xff0c;主要用于在线分析处理查询(OLAP)&#xff0c;能够使用SQL查询实时生成分析数据报告 2.clickHouse的特点 2.1列式存储 对于列的聚合&…

城市内涝排水新模式:慧天[HTWATER]

慧天[HTWATER]软件&#xff1a;慧天排水数字化分析平台针对城市排水系统基础设施数据管理的需求&#xff0c;以及水文、水力及水质模拟对数据的需求&#xff0c;实现了以数据库方式对相应数据的存储。可以对分流制排水系统及合流制排水系统进行地表水文、管网水力、水质过程的模…

Transformers 直观解释——不仅是如何工作,而且为什么工作得这么好

输入序列如何到达Attention模块 注意力模块存在于编码器堆栈中的每个编码器中&#xff0c;以及解码器堆栈中的每个解码器中。我们将首先放大编码器的注意力。 Attention in the Encoder&#xff1a; 举个例子&#xff0c;假设我们正在研究一个英语到西班牙语的翻译问题&…

【旅游】泉州攻略v1.0.0

一、泉州古城 泉州市距离深圳大约520公里&#xff0c;从深圳北站出发&#xff0c;高铁大约3小时30分。 到达泉州西站后&#xff0c;往东南方向大约8公里&#xff0c;就可以到达主要的旅游景点泉州古城。 古城很适合使用一天玩耍&#xff0c;核心路线如下&#xff1a; 一路的景…