【总结】ITOO在线编辑性能优化——多线程

2024-08-27 15:18

本文主要是介绍【总结】ITOO在线编辑性能优化——多线程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

   项目背景

           

     

问题:

      由上图可以知道,“页面需要根据试卷id获取全部的试卷信息”,由下面代码可以看出根据返回的“returnPaperDetail”进行开始进行嵌套循环操作。
     图解:
  

       具体代码如下
     
  
/**
* 功能:queryAllQuestion
* 描述:加载页面查询出所有表的数据
* 主要实体:ExaminationPaper(4张表的联合:questionMain,questionSub,paperMain,paperSub)
* 作者:十一期 谭倩倩
* 时间:2016-6-18
* 修改人:
* 修改时间:
* @param request
* @param response
*/
@RequestMapping("/queryAllQuestion")
public void queryAllQuestion(HttpServletRequest request,HttpServletResponse response)
{
//1.抽取paperMain
ExaminationPaper examinationPaper=new ExaminationPaper();
String paperMainId=paperId.replace("'", "");//暂时使用假数据
String dataBaseName="itoo_exam";
PaperMain RepaperMain=paperMainBean.queryPaperMainById(paperMainId, dataBaseName);
examinationPaper.setId(paperMainId);
examinationPaper.setPaperName(RepaperMain.getComment());
examinationPaper.setPaperScore(RepaperMain.getScore());
//2. 抽取paperdetail和questionMain数据(嵌套循环)
List<PaperDetail> returnPaperDetail=this.ReturnqueryPaperDetail(paperMainId, dataBaseName);
List<QuestionMain> RequestionMainList=new ArrayList<QuestionMain>();
List<QuestionSub> RequestionSubList=new ArrayList<QuestionSub>();
//循环paperdetail
for (PaperDetail returnSinglePaperDetail : returnPaperDetail)
{
RequestionMainList=this.ReturnQuestionMain(returnSinglePaperDetail.getId(), dataBaseName);
RequestionMainList = orderByQuestionMainList(RequestionMainList);
for (QuestionMain returnSinglequestionMain : RequestionMainList)
{
RequestionSubList=this.ReturnQuestionSub(returnSinglequestionMain.getId(), dataBaseName);
returnSinglequestionMain.setOptions(RequestionSubList);
}
//查询出来的组件
List<QuestionTypeDetail> lstQuestionTypeDetail = paperMainBean.queryComponentById(
returnSinglePaperDetail.getQuestionTypeId(), dataBaseName);
returnSinglePaperDetail.setLstQuestionTypeDetail(lstQuestionTypeDetail);
//把组件的英文名称装到“returnSinglePaperDetail”里面
returnSinglePaperDetail.setLstQuestionMain(RequestionMainList);
 
}
examinationPaper.setPaperDetails(returnPaperDetail);
jacksonJson.beanToJson(response, examinationPaper);
}
 
/**
* @param RequestionMainList
* @return
*/
private List<QuestionMain> orderByQuestionMainList(
List<QuestionMain> RequestionMainList) {
/**对大小题进行排序思路:
// * ①定义一个 List<QuestionMain> bigLittleQuestion 用于存放排好序的大小题。
// * ②判断查出来的题型是大小题,则先筛选大题。
// * ③如果是大题,将其放到bigLittleQuestion中。
// * 然后遍历所有题目,找到该大题对应的所有小题。放到bigLittleQuestion中。
// *
// *
// */
………………………………………………………………
}

【解决方案】


        一套试卷有多个题型,那么我就设置每个题型为一个线程。

   图示:




代码如下:
      大体是实例化一个线程池,根据题目数量的多少来添加多少个线程,一个题型代表一个线程,最后遍历线程结果。
  
  
public void queryAllQuestion(HttpServletRequest request,HttpServletResponse response)
{
//1.抽取paperMain
ExaminationPaper examinationPaper=new ExaminationPaper();
String paperMainId=paperId.replace("'", "");//暂时使用假数据
String dataBaseName="itoo_exam";
PaperMain RepaperMain=paperMainBean.queryPaperMainById(paperMainId, dataBaseName);
examinationPaper.setId(paperMainId);
examinationPaper.setPaperName(RepaperMain.getComment());
examinationPaper.setPaperScore(RepaperMain.getScore());
//2. 抽取paperdetail和questionMain数据(嵌套循环)
List<PaperDetail> returnPaperDetail=this.ReturnqueryPaperDetail(paperMainId, dataBaseName);
//测试加上线程的时间
long startTime=System.currentTimeMillis();
int count=returnPaperDetail.size();
//创建一个线程池
ExecutorService executorService = Executors.newCachedThreadPool();
List<Future<PaperDetail>> resultList = new ArrayList<Future<PaperDetail>>();
for (PaperDetail returnSinglePaperDetail : returnPaperDetail) {
//使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中
Future<PaperDetail> future = executorService.submit(new myCallable(returnSinglePaperDetail));
//将任务执行结果存储到List中
resultList.add(future);
}
List<PaperDetail> listPapaerDeatil=new ArrayList<PaperDetail>();
//遍历任务的结果
for (Future<PaperDetail> fp: resultList) {
try {
PaperDetail enPaperDetail =fp.get();
listPapaerDeatil.add(enPaperDetail);
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//启动一次顺序关闭,执行以前提交的任务,但不接受新任务。如果已经关闭,则调用没有其他作用。
executorService.shutdown();
}
examinationPaper.setPaperDetails(listPapaerDeatil);
long endTime=System.currentTimeMillis();
System.out.println(endTime-startTime);
 
jacksonJson.beanToJson(response, examinationPaper);
}

   
/**
* 多线程进行题干和选项查询。
* @author 十一期 谭倩倩
*
*/
@SuppressWarnings("unchecked")
public class myCallable implements Callable<PaperDetail>{
private PaperDetail paperDetail;
public myCallable(PaperDetail paperDetail) {
this.paperDetail = paperDetail;
}
String dataBaseName="itoo_exam";
public PaperDetail call(){
List<QuestionMain> RequestionMainList=questionMainBean.queryQuestionbankList(paperDetail.getId(), dataBaseName);
RequestionMainList = orderByQuestionMainList(RequestionMainList);
for (QuestionMain returnSinglequestionMain : RequestionMainList)
{
List<QuestionSub> RequestionSubList=questionSubBean.queryQuestionbankOptionsList(returnSinglequestionMain.getId(), dataBaseName);
returnSinglequestionMain.setOptions(RequestionSubList);
}
//查询出来的组件
List<QuestionTypeDetail> lstQuestionTypeDetail = paperMainBean.queryComponentById(
paperDetail.getQuestionTypeId(), dataBaseName);
paperDetail.setLstQuestionTypeDetail(lstQuestionTypeDetail);
//把组件的英文名称装到“returnSinglePaperDetail”里面
paperDetail.setLstQuestionMain(RequestionMainList);
return paperDetail;
}
}


【结果】

没有用线程的结果是:
(第一套测试卷子)


(第二套测试卷子)



用了线程的结果是:

(第一套测试卷子)




(第二套测试卷子)




【总结】

      还需要优化的性能:

      1. 算法优化


        (需要优化的代码)
  
private List<QuestionMain> orderByQuestionMainList(
List<QuestionMain> RequestionMainList) {
/**对大小题进行排序思路:
// * ①定义一个 List<QuestionMain> bigLittleQuestion 用于存放排好序的大小题。
// * ②判断查出来的题型是大小题,则先筛选大题。
// * ③如果是大题,将其放到bigLittleQuestion中。
// * 然后遍历所有题目,找到该大题对应的所有小题。放到bigLittleQuestion中。
// *
// * 仍需要优化
// */
if (RequestionMainList!=null && RequestionMainList.size()>1 )
{
if ( RequestionMainList.get(0).getIsParentQuestion()==1 || RequestionMainList.get(0).getParentQuestionId()!=null)
{//筛选是大小题
List<QuestionMain> bigLittleQuestion=new ArrayList<QuestionMain>();
for (int i = 0; i < RequestionMainList.size(); i++)
{
if (RequestionMainList.get(i).getIsParentQuestion()==1)
{//查找出所有的大题干
bigLittleQuestion.add(RequestionMainList.get(i));
//查找该大题干下面所有的小题干
for (int j = 0; j < RequestionMainList.size(); j++)
{
//匹配该大题干下面的小题干
if(RequestionMainList.get(j).getParentQuestionId()!=null)
{
if (RequestionMainList.get(j).getParentQuestionId().equals(RequestionMainList.get(i).getId()))
{
bigLittleQuestion.add(RequestionMainList.get(j));
}
}
}
}
}
RequestionMainList=bigLittleQuestion;
}
}
return RequestionMainList;
}

      2. 批量查询或者缓存


         (需要优化的代码)
  
for (QuestionMain returnSinglequestionMain : RequestionMainList)
{
List<QuestionSub> RequestionSubList=questionSubBean.queryQuestionbankOptionsList(returnSinglequestionMain.getId(), dataBaseName);

这篇关于【总结】ITOO在线编辑性能优化——多线程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112032

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

电力系统中的A类在线监测装置—APView400

随着电力系统的日益复杂和人们对电能质量要求的提高,电能质量在线监测装置在电力系统中得到广泛应用。目前,市场上的在线监测装置主要分为A类和B类两种类型,A类和B类在线监测装置主要区别在于应用场景、技术参数、通讯协议和扩展性。选择时应根据实际需求和应用场景综合考虑,并定期维护和校准。电能质量在线监测装置是用于实时监测电力系统中的电能质量参数的设备。 APView400电能质量A类在线监测装置以其多核

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份