【总结】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

相关文章

kkFileView在线预览office的常见问题以及解决方案

《kkFileView在线预览office的常见问题以及解决方案》kkFileView在线预览Office常见问题包括base64编码配置、Office组件安装、乱码处理及水印添加,解决方案涉及版本适... 目录kkFileView在线预览office的常见问题1.base642.提示找不到OFFICE组件

RabbitMQ消费端单线程与多线程案例讲解

《RabbitMQ消费端单线程与多线程案例讲解》文章解析RabbitMQ消费端单线程与多线程处理机制,说明concurrency控制消费者数量,max-concurrency控制最大线程数,prefe... 目录 一、基础概念详细解释:举个例子:✅ 单消费者 + 单线程消费❌ 单消费者 + 多线程消费❌ 多

Linux下在线安装启动VNC教程

《Linux下在线安装启动VNC教程》本文指导在CentOS7上在线安装VNC,包含安装、配置密码、启动/停止、清理重启步骤及注意事项,强调需安装VNC桌面以避免黑屏,并解决端口冲突和目录权限问题... 目录描述安装VNC安装 VNC 桌面可能遇到的问题总结描js述linux中的VNC就类似于Window

小白也能轻松上手! 路由器设置优化指南

《小白也能轻松上手!路由器设置优化指南》在日常生活中,我们常常会遇到WiFi网速慢的问题,这主要受到三个方面的影响,首要原因是WiFi产品的配置优化不合理,其次是硬件性能的不足,以及宽带线路本身的质... 在数字化时代,网络已成为生活必需品,追剧、游戏、办公、学习都离不开稳定高速的网络。但很多人面对新路由器

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三

Zabbix在MySQL性能监控方面的运用及最佳实践记录

《Zabbix在MySQL性能监控方面的运用及最佳实践记录》Zabbix通过自定义脚本和内置模板监控MySQL核心指标(连接、查询、资源、复制),支持自动发现多实例及告警通知,结合可视化仪表盘,可有效... 目录一、核心监控指标及配置1. 关键监控指标示例2. 配置方法二、自动发现与多实例管理1. 实践步骤

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u