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

相关文章

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

MyBatisPlus如何优化千万级数据的CRUD

《MyBatisPlus如何优化千万级数据的CRUD》最近负责的一个项目,数据库表量级破千万,每次执行CRUD都像走钢丝,稍有不慎就引起数据库报警,本文就结合这个项目的实战经验,聊聊MyBatisPl... 目录背景一、MyBATis Plus 简介二、千万级数据的挑战三、优化 CRUD 的关键策略1. 查

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

基于Python实现一个简单的题库与在线考试系统

《基于Python实现一个简单的题库与在线考试系统》在当今信息化教育时代,在线学习与考试系统已成为教育技术领域的重要组成部分,本文就来介绍一下如何使用Python和PyQt5框架开发一个名为白泽题库系... 目录概述功能特点界面展示系统架构设计类结构图Excel题库填写格式模板题库题目填写格式表核心数据结构

Nginx Location映射规则总结归纳与最佳实践

《NginxLocation映射规则总结归纳与最佳实践》Nginx的location指令是配置请求路由的核心机制,其匹配规则直接影响请求的处理流程,下面给大家介绍NginxLocation映射规则... 目录一、Location匹配规则与优先级1. 匹配模式2. 优先级顺序3. 匹配示例二、Proxy_pa

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio