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

相关文章

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

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta