遇到了业务上处理很慢的情况,都可以用多线程解决,这是原先未优化的代码
/**
* 导出excel
*/
@GetMapping("/export/excel")
@ApiOperationSupport(order = 11)
@ApiOperation(value = "导出excel", notes = "传入gaugeRecord")
public void exportExcel(GaugeRecordEntity gaugeRecord, HttpServletResponse response) throws IOException {
GaugeTestEntity testCondition = new GaugeTestEntity();
testCondition.setBatchId(gaugeRecord.getBatchId());
// testCondition.setSiteCode(gaugeRecord.getSiteCode());
// 查询所有人的基本信息
List allTesters = testerService.list();
// 将所有人的信息转换为 id 和 entity 的 HashMap
Map testerMap = allTesters.stream()
.collect(Collectors.toMap(TesterEntity::getIdNo, Function.identity()));
List gauges = gaugeTestService.selectEffectiveGauge(testCondition);
List excels = gauges.stream().map(g -> {
TesterEntity tester = testerMap.get(g.getUserId());
GaugeTestExcel e = new GaugeTestExcel();
e.setUserId(g.getUserId());
e.setUserName(g.getUserName());
e.setTestTime(g.getTestTime());
e.setGender(CommonUtil.getGender(g.getUserId())==1?"男":"女");
e.setBirthday(CommonUtil.getBirthday(g.getUserId()));
// e.setBirthdayText(e.getBirthday()==null?"":e.getBirthday().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
if (tester != null) {
e.setEducationText(DictBizCache.getValue(DictBizEnum.EDUCATION, tester.getEducation()));
e.setEducationYears(tester.getEducationYears());
e.setIsOnlychildText(DictBizCache.getValue(DictBizEnum.ONLY_CHILD, tester.getIsOnlychild()));
if (!DictBizCache.getValue(DictBizEnum.ONLY_CHILD, tester.getIsOnlychild()).equals("独生子女")) {
e.setChildrenQty(tester.getChildrenQty());
e.setChildrenRanking(tester.getChildrenRanking());
}
e.setSubjectiveSes(tester.getSubjectiveSes());
e.setFamilyMonthlyEarningText(DictBizCache.getValue(DictBizEnum.FAMILY_MONTHLY_EARNING, tester.getFamilyMonthlyEarning()));
e.setEducationMotherText(DictBizCache.getValue(DictBizEnum.PARENT_EDUCATION, tester.getEducationMother()));
e.setEducationFantherText(DictBizCache.getValue(DictBizEnum.PARENT_EDUCATION, tester.getEducationFanther()));
}
JSONObject statistical = JSON.parseObject(g.getStatistical());
e.setTaiyin(statistical.get("太阴人格") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("太阴人格").toString()));
e.setYanjinxing(statistical.get("严谨性人格") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("严谨性人格").toString()));
e.setShenjingzhi(statistical.get("神经质人格") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("神经质人格").toString()));
e.setRengetezhi(statistical.get("人格特质") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("人格特质").toString()));
e.setTezhijiaolv(statistical.get("特质焦虑") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("特质焦虑").toString()));
e.setShenghuomanyidu(statistical.get("生活满意度") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("生活满意度").toString()));
e.setShengmingyiyigan(statistical.get("生命意义感") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("生命意义感").toString()));
e.setZizun(statistical.get("自尊") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("自尊").toString()));
e.setZhuguanxingfugan(statistical.get("主观幸福感") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("主观幸福感").toString()));
e.setYalizhijue(statistical.get("压力知觉") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("压力知觉").toString()));
e.setYiyu(statistical.get("抑郁") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("抑郁").toString()));
e.setXinlijiankang(statistical.get("心理健康") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("心理健康").toString()));
e.setJijiyingdui(statistical.get("积极应对") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("积极应对").toString()));
e.setXiaojiyingdui(statistical.get("消极应对") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("消极应对").toString()));
e.setQingxutiaojie(statistical.get("情绪调节") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("情绪调节").toString()));
e.setXinlitanxing(statistical.get("心理弹性") == null ? BigDeci服务器托管mal.ZERO : new BigDecimal(statistical.get("心理弹性").toString()));
e.setZiwoxiaonenggan(statistical.get("自我效能感") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("自我效能感").toString()));
e.setYaliyingdui(statistical.get("压力应对") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("压力应对").toString()));
e.setRenjiqinggan(statistical.get("人际情感") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("人际情感").toString()));
e.setRenjichongtu(statistical.get("人际冲突") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("人际冲突").toString()));
e.setQinshehui(statistical.get("亲社会倾向") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("亲社会倾向").toString()));
e.setGongji(statistical.get("攻击") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("攻击").toString()));
e.setRenjiguanxi(statistical.get("人际关系") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("人际关系").toString()));
e.setShiyingnengli(statistical.get("适应能力") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("适应能力").toString()));
JSONObject answer = JSON.parseObject(g.getUserAnswer());
e.setQ1((String) answer.get("Q1"));
e.setQ2((String) answer.get("Q2"));
e.setQ3((String) answer.get("Q3"));
e.setQ4((String) answer.get("Q4"));
e.setQ5((String) answer.get("Q5"));
e.setQ6((String) answer.get("Q6"));
e.setQ7((String) answer.get("Q7"));
e.setQ8((String) answer.get("Q8"));
e.setQ9((String) answer.get("Q9"));
e.setQ10((String) answer.get("Q10"));
e.setQ11((String) answer.get("Q11"));
e.setQ12((String) answer.get("Q12"));
e.setQ13((String) answer.get("Q13"));
e.setQ14((String) answer.get("Q14"));
e.setQ15((String) answer.get("Q15"));
e.setQ16((String) answer.get("Q16"));
e.setQ17((String) answer.get("Q17"));
e.setQ18((String) answer.get("Q18"));
e.setQ19((String) answer.get("Q19"));
e.setQ20((String) answer.get("Q20"));
e.setQ21((String) answer.get("Q21"));
e.setQ22((String) answer.get("Q22"));
e.setQ23((String) answer.get("Q23"));
e.setQ24((String) answer.get("Q24"));
e.setQ25((String) answer.get("Q25"));
e.setQ26((String) answer.get("Q26"));
e.setQ27((String) answer.get("Q27"));
e.setQ28((String) answer.get("Q28"));
e.setQ29((String) answer.get("Q29"));
e.setQ30((String) answer.get("Q30"));
e.setQ31((String) answer.get("Q31"));
e.setQ32((String) answer.get("Q32"));
e.setQ33((String) answer.get("Q33"));
e.setQ34((String) answer.get("Q34"));
e.setQ35((String) answer.get("Q35"));
e.setQ36((String) answer.get("Q36"));
e.setQ37((String) answer.get("Q37"));
e.setQ38((String) answer.get("Q38"));
e.setQ39((String) answer.get("Q39"));
e.setQ40((String) answer.get("Q40"));
e.setQ41((String) answer.get("Q41"));
e.setQ42((String) answer.get("Q42"));
e.setQ43((String) answer.get("Q43"));
e.setQ44((String) answer.get("Q44"));
e.setQ45((String) answer.get("Q45"));
e.setQ46((String) answer.get("Q46"));
e.setQ47((String) answer.get("Q47"));
e.setQ48((String) answer.get("Q48"));
e.setQ49((String) answer.get("Q49"));
e.setQ50((String) answer.get("Q50"));
e.setQ51((String) answer.get("Q51"));
e.setQ52((String) answer.get("Q52"));
e.setQ53((String) answer.get("Q53"));
e.setQ54((String) answer.get("Q54"));
e.setQ55((String) answer.get("Q55"));
e.setQ56((String) answer.get("Q56"));
e.setQ57((String) answer.get("Q57"));
e.setQ58((String) answer.get("Q58"));
e.setQ59((String) answer.get("Q59"));
return e;
}).collect(Collectors.toList());
//查询工作记忆任务
List gaugesGong = gaugeTestService.list(new QueryWrapper().lambda().eq(GaugeTestEntity::getBatchId, gaugeRecord.getBatchId()).eq(GaugeTestEntity::getTestType, 1707));
List nbackExcels = gaugesGong.stream().map(g -> {
TesterEntity tester = testerService.selectByIdNo(g.getUserId());
NBackTestExcel e = new NBackTestExcel();
e.setUserId(g.getUserId());
e.setUserName(g.getUserName());
e.setTestTime(g.getTestTime());
e.setGender(CommonUtil.getGender(g.getUserId())==1?"男":"女");
e.setBirthday(CommonUtil.getBirthday(g.getUserId()));
// e.setBirthdayText(e.getBirthday()==null?"":e.getBirthday().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
if (tester != null) {
}
//构建hashMap来存各个block的对象
HashMap> nbackListHashMap = new HashMap();
ArrayList nBlackJsonVOS = new ArrayList();//
JSONArray jsonArrayNBack = JSON.parseArray(g.getUserAnswer());//一共160个
for (int i = 0; i ();
}
}
//循环遍历我的map
int totalAccuracyOfVisualNumber = 0;
ArrayList totalReactionTimeList = new ArrayList();// 用于全部Block记录每轮的反应时间
for (Map.Entry> entry : nbackListHashMap.entrySet()) {
// 创建一个数组来存储每轮的反应时间
ArrayList reactionTimeList = new ArrayList();// 用于记录每轮的反应时间
int omissionErrorNumber = 0;//漏报次数 为2的
int incorrectClassificationsNumber = 0; //错误次数 为4的
int accuracyNnmber = 0;//其他
Integer visualTestCategory = 1;//视觉分类任务
Integer blockNum = null;
Integer difficultyLevel = null;
List nabckList = entry.getValue();
for (NBlackJsonVO nBlackJsonVO : nabckList) {
String timer = nBlackJsonVO.getTimer();
// 获取当前轮的 blockNum
blockNum = Integer.parseInt(nBlackJsonVO.getBlockNum());
// 获取难度等级
difficultyLevel = Integer.parseInt(nBlackJsonVO.getLevel());
// 将反应时间转换为 BigDecimal
if (timer != null && !timer.isEmpty()) {
// 将字符串转换为 BigDecimal
BigDecimal currentReactionTime = new BigDecimal(timer);
// 将当前轮的反应时间添加到总时间中
reactionTimeList.add(currentReactionTime.intValue());
//这个人所有back的用时数据
totalReactionTimeList.add(currentReactionTime.intValue());
}
int sdtTask1 = Integer.parseInt(nBlackJsonVO.getSDTTask1());
switch (sdtTask1) {
case 2: // 漏报次数为2的情况
omissionErrorNumber++;
break;
case 4: // 错误次数为4的情况
incorrectClassificationsNumber++;
break;
default: // 其他情况
accuracyNnmber++;//每个Nback正确数
totalAccuracyOfVisualNumber++;//总正确数
break;
}
}
// 计算平均反应时间
// 计算平均反应时间
double averageReactionTime = reactionTimeList.stream()
.mapToDouble(Integer::doubleValue)
.average()
.orElse(0.0);
double averageReactionTimeOfCorrectVisualAnswers = totalReactionTimeList.stream()
.mapToDouble(Integer::doubleValue)
.average()
.orElse(0.0);
// 将平均时间四舍五入到整数
int roundedAverageTime = (int) Math.round(averageReactionTime);
int totalaverageReactionTimeOfCorrectVisualAnswers = (int) Math.round(averageReactionTimeOfCorrectVisualAnswers);
BigDecimal accuracyRate = new BigDecimal(accuracyNnmber).divide(new BigDecimal(20), 2, RoundingMode.HALF_UP);
BlockExcelVO blockExcelVO = new BlockExcelVO();
blockExcelVO.setBlock(blockNum);
blockExcelVO.setAccuracyRate(accuracyRate);
blockExcelVO.setIncorrectClassificationsNumber(incorrectClassificationsNumber);
blockExcelVO.setOmissionErrorNumber(omissionErrorNumber);
blockExcelVO.setDifficultyLevel(difficultyLevel);
blockExcelVO.setReactionTime(roundedAverageTime);
blockExcelVO.setVisualTestCategory(1);//类别都是1
//利用反射填充属性
this.fillFieldsForNBack(e, blockExcelVO);
e.setCompletionTime(g.getTotalTime());
e.setAverageReactionTimeOfCorrectVisualAnswers(totalaverageReactionTimeOfCorrectVisualAnswers);
//算出总正确率
BigDecimal totalAccuracyOfVisualRate = new BigDecimal(totalAccuracyOfVisualNumber).divide(new BigDecimal(160), 2, RoundingMode.HALF_UP);
e.setTotalAccuracyOfVisualRate(totalAccuracyOfVisualRate);
System.out.println(e);
}
return e;
}).collect(Collectors.toList());
//查询情绪调节任务
List gaugesEmotionaTestlList = gaugeTestService.list(new QueryWrapper().lambda().eq(GaugeTestEntity::getBatchId, gaugeRecord.getBatchId()).eq(GaugeTestEntity::getTestType, 1703));
List emotionalRegulationExcelList = gaugesEmotionaTestlList.stream().map(g -> {
TesterEntity tester = testerService.selectByIdNo(g.getUserId());
EmotionalRegulationExcel e = new EmotionalRegulationExcel();
e.setUserId(g.getUserId());
e.setUserName(g.getUserName());
e.setTestTime(g.getTestTime());
e.setGender(CommonUtil.getGender(g.getUserId())==1?"男":"女");
e.setBirthday(CommonUtil.getBirthday(g.getUserId()));
e.setCompletionTime(g.getTotalTime());
// e.setNaturalEmotionalResponseScore();//自然情绪得分
// e.setEmotionalRegulationAbilityScore();//情绪调节能力得分
// e.setBirthdayText(e.getBirthday()==null?"":e.getBirthday().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
if (tester != null) {
}
JSONArray jsonArrayQing = JSON.parseArray(g.getUserAnswer());
ArrayList aversiveNums = new ArrayList();
ArrayList neutralNums = new ArrayList();
for (int i = 0; i aversiveNum_0_20 = aversiveNums.subList(0, 20);
List neutralNum_0_20 = neutralNums.subList(0, 20);
List aversiveNum_0_35 = aversiveNums.subList(0, 35);
// 计算平均反应时间
double averageAversiveNum_0_20 = aversiveNum_0_20.stream()
.mapToDouble(Integer::doubleValue)
.average()
.orElse(0.0);
double averageNeutralNum_0_20 = neutralNum_0_20.stream()
.mapToDouble(Integer::doubleValue)
.average()
.orElse(0.0);
double averageAversiveNum_0_35 = aversiveNum_0_35.stream()
.mapToDouble(Integer::doubleValue)
.average()
.orElse(0.0);
BigDecimal subtract0 = new BigDecimal(averageAversiveNum_0_20).subtract(new BigDecimal(averageNeutralNum_0_20));
BigDecimal subtract1 = new BigDecimal(averageAversiveNum_0_20).subtract(new BigDecimal(averageAversiveNum_0_35));
// e.setNaturalEmotionalResponseScore(subtract0); 这俩先不导出,因为规则有问题
// e.setEmotionalRegulationAbilityScore(subtract1);
return e;
}).collect(Collectors.toList());
// 设置响应类型为Excel文件
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("UTF-8");
// 设置Excel文件名
response.setHeader("Content-disposition", "attachment;filename=" + "SYNL" + ".xlsx");
try {
if (!CollectionUtils.isEmpty(excels)) {
// 创建ExcelWriter并指定输出流为response.getOutputStream()
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).excelType(ExcelTypeEnum.XLSX).build();
// 写入三个sheet的数据
WriteSheet writeSheet = EasyExcel.writerSheet(0, "适应能力").head(GaugeTestExcel.class).build();
excelWriter.write(excels, writeSheet);
WriteSheet writeSheet1 = EasyExcel.writerSheet(1, "工作记忆任务").head(NBackTestExcel.class).build();
excelWriter.write(nbackExcels, writeSheet1);
WriteSheet writeSheet2 = EasyExcel.writerSheet(2, "情绪调节任务").head(EmotionalRegulationExcel.class).build();
excelWriter.write(emotionalRegulationExcelList, writeSheet2);
excelWriter.finish();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.getOutputStream().flush();
response.getOutputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
三个list本质上并没有关联,可以分开处理,利用三个线程正好,等待处理完成,把list收集起来
,改良后
/**
* 导出excel
*/
@GetMapping("/export/excel")
@ApiOperationSupport(order = 11)
@ApiOperation(value = "导出excel", notes = "传入gaugeRecord")
public void exportExcel(GaugeRecordEntity gaugeRecord, HttpServletResponse response) throws IOException {
GaugeTestEntity testCondition = new GaugeTestEntity();
testCondition.setBatchId(gaugeRecord.getBatchId());
// testCondition.setSiteCode(gaugeRecord.getSiteCode());
// 查询所有人的基本信息
List allTesters = testerService.list();
// 将所有人的信息转换为 id 和 entity 的 HashMap
Map testerMap = allTesters.stream()
.collect(Collectors.toMap(TesterEntity::getIdNo, Function.identity()));
List excels = null;
List nbackExcels= null;
List emotionalRegulationExcelList = null;
AtomicReference> excelsRef = new AtomicReference(excels);
AtomicReference> excelsRef02 = new AtomicReference(nbackExcels);
AtomicReference> excelsRef03 = new AtomicReference(emotionalRegulationExcelList);
// 使用线程池并行处理不同的数据导出任务
//输出线程号加上时间
System.out.println("当前线程"+Thread.currentThread().getId() + " " + LocalDateTime.now());
ExecutorService executorService = Executors.newFixedThreadPool(3);
CompletableFuture task1 = CompletableFuture.runAsync(() -> {
List gauges = gaugeTestService.selectEffectiveGauge(testCondition);
List excelsAsync = gauges.stream().map(g -> {
TesterEntity tester = testerMap.get(g.getUserId());
GaugeTestExcel e = new GaugeTestExcel();
e.setUserId(g.getUserId());
e.setUserName(g.getUserName());
e.setTestTime(g.getTestTime());
e.setGender(CommonUtil.getGender(g.getUserId()) == 1 ? "男" : "女");
e.setBirthday(CommonUtil.getBirthday(g.getUserId()));
// e.setBirthdayText(e.getBirthday()==null?"":e.getBirthday().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
if (tester != null) {
e.setEducationText(DictBizCache.getValue(DictBizEnum.EDUCATION, tester.getEducation()));
e.setEducationYears(tester.getEducationYears());
e.setIsOnlychildText(DictBizCache.getValue(DictBizEnum.ONLY_CHILD, tester.getIsOnlychild()));
if (!DictBizCache.getValue(DictBizEnum.ONLY_CHILD, tester.getIsOnlychild()).equals("独生子女")) {
e.setChildrenQty(tester.getChildrenQty());
e.setChildrenRanking(tester.getChildrenRanking());
}
e.setSubjectiveSes(tester.getSubjectiveSes());
e.setFamilyMonthlyEarningText(DictBizCache.getValue(DictBizEnum.FAMILY_MONTHLY_EARNING, tester.getFamilyMonthlyEarning()));
e.setEducationMotherText(DictBizCache.getValue(DictBizEnum.PARENT_EDUCATION, tester.getEducationMother()));
e.setEducationFantherText(DictBizCache.getValue(DictBizEnum.PARENT_EDUCATION, tester.getEducationFanther()));
}
JSONObject statistical = JSON.parseObject(g.getStatistical());
e.setTaiyin(statistical.get("太阴人格") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("太阴人格").toString()));
e.setYanjinxing(statistical.get("严谨性人格") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("严谨性人格").toString()));
e.setShenjingzhi(statistical.get("神经质人格") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("神经质人格").toString()));
e.setRengetezhi(statistical.get("人格特质") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("人格特质").toString()));
e.setTezhijiaolv(statistical.get("特质焦虑") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("特质焦虑").toString()));
e.setShenghuomanyidu(statistical.get("生活满意度") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("生活满意度").toString()));
e.setShengmingyiyigan(statistical.get("生命意义感") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("生命意义感").toString()));
e.setZizun(statistical.get("自尊") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("自尊").toString()));
e.setZhuguanxingfugan(statistical.get("主观幸福感") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("主观幸福感").toString()));
e.setYalizhijue(statistical.get("压力知觉") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("压力知觉").toString()));
e.setYiyu(statistical.get("抑郁") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("抑郁").toString()));
e.setXinlijiankang(statistical.get("心理健康") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("心理健康").toString()));
e.setJijiyingdui(statistical.get("积极应对") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("积极应对").toString()));
e.setXiaojiyingdui(statistical.get("消极应对") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("消极应对").toString()));
e.setQingxutiaojie(statistical.get("情绪调节") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("情绪调节").toString()));
e.setXinlitanxing(statistical.get("心理弹性") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("心理弹性").toString()));
e.setZiwoxiaonenggan(statistical.get("自我效能感") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("自我效能感").toString()));
e.setYaliyingdui(statistical.get("压力应对") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("压力应对").toString()));
e.setRenjiqinggan(statistical.get("人际情感") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("人际情感").toString()));
e.setRenjichongtu(statistical.get("人际冲突") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("人际冲突").toString()));
e.setQinshehui(statistical.get("亲社会倾向") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("亲社会倾向").toString()));
e.setGongji(statistical.get("攻击") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("攻击").toString()));
e.setRenjiguanxi(statistical.get("人际关系") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("人际关系").toString()));
e.setShiyingnengli(statistical.get("适应能力") == null ? BigDecimal.ZERO : new BigDecimal(statistical.get("适应能力").toString()));
JSONObject answer = JSON.parseObject(g.getUserAnswer());
e.setQ1((String) answer.get("Q1"));
e.setQ2((String) answer.get("Q2"));
e.setQ3((String) answer.get("Q3"));
e.setQ4((String) answer.get("Q4"));
e.setQ5((String) answer.get("Q5"));
e.setQ6((String) answer.get("Q6"));
e.setQ7((String) answer.get("Q7"));
e.setQ8((String) answer.get("Q8"));
e.setQ9((String) answer.get("Q9"));
e.setQ10((String) answer.get("Q10"));
e.setQ11((String) answer.get("Q11"));
e.setQ12((String) answer.get("Q12"));
e.setQ13((String) answer.get("Q13"));
e.setQ14((String) answer.get("Q14"));
e.setQ15((String) answer.get("Q15"));
e.setQ16((String) answer.get("Q16"));
e.setQ17((String) answer.get("Q17"));
e.setQ18((String) answer.get("Q18"));
e.setQ19((String) answer.get("Q19"));
e.setQ20((String) answer.get("Q20"));
e.setQ21((String) answer.get("Q21"));
e.setQ22((String) answer.get("Q22"));
e.setQ23((String) answer.get("Q23"));
e.setQ24((String) answer.get("Q24"));
e.setQ25((String) answer.get("Q25"));
e.setQ26((String) answer.get("Q26"));
e.setQ27((String) answer.get("Q27"));
e.setQ28((String) answer.get("Q28"));
e.setQ29((String) answer.get("Q29"));
e.setQ30((String) answer.get("Q30"));
e.setQ31((String) answer.get("Q31"));
e.setQ32((String) answer.get("Q32"));
e.setQ33((String) answer.get("Q33"));
e.setQ34((String) answer.get("Q34"));
e.setQ35((String) answer.get("Q35"));
e.setQ36((String) answer.get("Q36"));
e.setQ37((String) answer.get("Q37"));
e.setQ38((String) answer.get("Q38"));
e.setQ39((String) answer.get("Q39"));
e.setQ40((String) answer.get("Q40"));
e.setQ41((String) answer.get("Q41"));
e.setQ42((String) answer.get("Q42"));
e.setQ43((String) answer.get("Q43"));
e.setQ44((String) answer.get("Q44"));
e.setQ45((String) answer.get("Q45"));
e.setQ46((String) answer.get("Q46"));
e.setQ47((String) answer.get("Q47"));
e.setQ48((String) answer.get("Q48"));
e.setQ49((String) answer.get("Q49"));
e.setQ50((String) answer.get("Q50"));
e.setQ51((String) answer.get("Q51"));
e.setQ52((String) answer.get("Q52"));
e.setQ53((String) answer.get("Q53"));
e.setQ54((String) answer.get("Q54"));
e.setQ55((String) answer.get("Q55"));
e.setQ56((String) answer.get("Q56"));
e.setQ57((String) answer.get("Q57"));
e.setQ58((String) answer.get("Q58"));
e.setQ59((String) answer.get("Q59"));
return e;
}).collect(Collectors.toList());
excelsRef.set(excelsAsync);
//输出线程号加上时间
System.out.println("当前线程"+Thread.currentThread().getId() + " " + LocalDateTime.now());
}, executorService);
//查询工作记忆任务
CompletableFuture task2 = CompletableFuture.runAsync(() -> {
List gaugesGong = gaugeTestService.list(new QueryWrapper().lambda().eq(GaugeTestEntity::getBatchId, gaugeRecord.getBatchId()).eq(GaugeTestEntity::getTestType, 1707));
List nbackExcelsAsync = gaugesGong.stream().map(g -> {
TesterEntity tester = testerService.selectByIdNo(g.getUserId());
NBackTestExcel e = new NBackTestExcel();
e.setUserId(g.getUserId());
e.setUserName(g.getUserName());
e.setTestTime(g.getTestTime());
e.setGender(CommonUtil.getGender(g.getUserId()) == 1 ? "男" : "女");
e.setBirthday(CommonUtil.getBirthday(g.getUserId()));
// e.setBirthdayText(e.getBirthday()==null?"":e.getBirthday().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
if (tester != null) {
}
//构建hashMap来存各个block的对象
HashMap> nbackListHashMap = new HashMap();
ArrayList nBlackJsonVOS = new ArrayList();//
JSONArray jsonArrayNBack = JSON.parseArray(g.getUserAnswer());//一共160个
for (int i = 0; i ();
}
}
//循环遍历我的map
int totalAccuracyOfVisualNumber = 0;
ArrayList totalReactionTimeList = new ArrayList();// 用于全部Block记录每轮的反应时间
for (Map.Entry> entry : nbackListHashMap.entrySet()) {
// 创建一个数组来存储每轮的反应时间
ArrayList reactionTimeList = new ArrayList();// 用于记录每轮的反应时间
int omissionErrorNumber = 0;//漏报次数 为2的
int incorrectClassificationsNumber = 0; //错误次数 为4的
int accuracyNnmber = 0;//其他
Integer visualTestCategory = 1;//视觉分类任务
Integer blockNum = null;
Integer difficultyLevel = null;
List nabckList = entry.getValue();
for (NBlackJsonVO nBlackJsonVO : nabckList) {
String timer = nBlackJsonVO.getTimer();
// 获取当前轮的 blockNum
blockNum = Integer.parseInt(nBlackJsonVO.getBlockNum());
// 获取难度等级
difficultyLevel = Integer.parseInt(nBlackJsonVO.getLevel());
// 将反应时间转换为 BigDecimal
if (timer != null && !timer.isEmpty()) {
// 将字符串转换为 BigDecimal
BigDecimal currentReactionTime = new BigDecimal(timer);
// 将当前轮的反应时间添加到总时间中
reactionTimeList.add(currentReactionTime.intValue());
//这个人所有back的用时数据
totalReactionTimeList.add(currentReactionTime.intValue());
}
int sdtTask1 = Integer.parseInt(nBlackJsonVO.getSDTTask1());
switch (sdtTask1) {
case 2: // 漏报次数为2的情况
omissionErrorNumber++;
break;
case 4: // 错误次数为4的情况
incorrectClassificationsNumber++;
break;
服务器托管 default: // 其他情况
accuracyNnmber++;//每个Nback正确数
totalAccuracyOfVisualNumber++;//总正确数
break;
}
}
// 计算平均反应时间
// 计算平均反应时间
double averageReactionTime = reactionTimeList.stream()
.mapToDouble(Integer::doubleValue)
.average()
.orElse(0.0);
double averageReactionTimeOfCorrectVisualAnswers = totalReactionTimeList.stream()
.mapToDouble(Integer::doubleValue)
.average()
.orElse(0.0);
// 将平均时间四舍五入到整数
int roundedAverageTime = (int) Math.round(averageReactionTime);
int totalaverageReactionTimeOfCorrectVisualAnswers = (int) Math.round(averageReactionTimeOfCorrectVisualAnswers);
BigDecimal accuracyRate = new BigDecimal(accuracyNnmber).divide(new BigDecimal(20), 2, RoundingMode.HALF_UP);
BlockExcelVO blockExcelVO = new BlockExcelVO();
blockExcelVO.setBlock(blockNum);
blockExcelVO.setAccuracyRate(accuracyRate);
blockExcelVO.setIncorrectClassificationsNumber(incorrectClassificationsNumber);
blockExcelVO.setOmissionErrorNumber(omissionErrorNumber);
blockExcelVO.setDifficultyLevel(difficultyLevel);
blockExcelVO.setReactionTime(roundedAverageTime);
blockExcelVO.setVisualTestCategory(1);//类别都是1
//利用反射填充属性
this.fillFieldsForNBack(e, blockExcelVO);
e.setCompletionTime(g.getTotalTime());
e.setAverageReactionTimeOfCorrectVisualAnswers(totalaverageReactionTimeOfCorrectVisualAnswers);
//算出总正确率
BigDecimal totalAccuracyOfVisualRate = new BigDecimal(totalAccuracyOfVisualNumber).divide(new BigDecimal(160), 2, RoundingMode.HALF_UP);
e.setTotalAccuracyOfVisualRate(totalAccuracyOfVisualRate);
System.out.println(e);
}
return e;
}).collect(Collectors.toList());
excelsRef02.set(nbackExcelsAsync);
//输出线程号加上时间
System.out.println("当前线程"+Thread.currentThread().getId() + " " + LocalDateTime.now());
}, executorService);
CompletableFuture task3 = CompletableFuture.runAsync(() -> {
//查询情绪调节任务
List gaugesEmotionaTestlList = gaugeTestService.list(new QueryWrapper().lambda().eq(GaugeTestEntity::getBatchId, gaugeRecord.getBatchId()).eq(GaugeTestEntity::getTestType, 1703));
List emotionalRegulationExcelListAsync = gaugesEmotionaTestlList.stream().map(g -> {
TesterEntity tester = testerService.selectByIdNo(g.getUserId());
EmotionalRegulationExcel e = new EmotionalRegulationExcel();
e.setUserId(g.getUserId());
e.setUserName(g.getUserName());
e.setTestTime(g.getTestTime());
e.setGender(CommonUtil.getGender(g.getUserId()) == 1 ? "男" : "女");
e.setBirthday(CommonUtil.getBirthday(g.getUserId()));
e.setCompletionTime(g.getTotalTime());
// e.setNaturalEmotionalResponseScore();//自然情绪得分
// e.setEmotionalRegulationAbilityScore();//情绪调节能力得分
// e.setBirthdayText(e.getBirthday()==null?"":e.getBirthday().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
if (tester != null) {
}
JSONArray jsonArrayQing = JSON.parseArray(g.getUserAnswer());
ArrayList aversiveNums = new ArrayList();
ArrayList neutralNums = new ArrayList();
for (int i = 0; i aversiveNum_0_20 = aversiveNums.subList(0, 20);
List neutralNum_0_20 = neutralNums.subList(0, 20);
List aversiveNum_0_35 = aversiveNums.subList(0, 35);
// 计算平均反应时间
double averageAversiveNum_0_20 = aversiveNum_0_20.stream()
.mapToDouble(Integer::doubleValue)
.average()
.orElse(0.0);
double averageNeutralNum_0_20 = neutralNum_0_20.stream()
.mapToDouble(Integer::doubleValue)
.average()
.orElse(0.0);
double averageAversiveNum_0_35 = aversiveNum_0_35.stream()
.mapToDouble(Integer::doubleValue)
.average()
.orElse(0.0);
BigDecimal subtract0 = new BigDecimal(averageAversiveNum_0_20).subtract(new BigDecimal(averageNeutralNum_0_20));
BigDecimal subtract1 = new BigDecimal(averageAversiveNum_0_20).subtract(new BigDecimal(averageAversiveNum_0_35));
// e.setNaturalEmotionalResponseScore(subtract0); 这俩先不导出,因为规则有问题
// e.setEmotionalRegulationAbilityScore(subtract1);
return e;
}).collect(Collectors.toList());
//输出线程号加上时间
System.out.println(Thread.currentThread().getId() + " " + LocalDateTime.now());
excelsRef03.set(emotionalRegulationExcelListAsync);
}, executorService);
// 等待所有任务完成
CompletableFuture.allOf(task1, task2, task3).join();
// 从AtomicReference获取最终的excels列表
excels = excelsRef.get();
nbackExcels = excelsRef02.get();
emotionalRegulationExcelList = excelsRef03.get();
// 设置响应类型为Excel文件
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("UTF-8");
// 设置Excel文件名
response.setHeader("Content-disposition", "attachment;filename=" + "SYNL" + ".xlsx");
try {
if (!CollectionUtils.isEmpty(excels)) {
// 创建ExcelWriter并指定输出流为response.getOutputStream()
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).excelType(ExcelTypeEnum.XLSX).build();
// 写入三个sheet的数据
WriteSheet writeSheet = EasyExcel.writerSheet(0, "适应能力").head(GaugeTestExcel.class).build();
excelWriter.write(excels, writeSheet);
WriteSheet writeSheet1 = EasyExcel.writerSheet(1, "工作记忆任务").head(NBackTestExcel.class).build();
excelWriter.write(nbackExcels, writeSheet1);
WriteSheet writeSheet2 = EasyExcel.writerSheet(2, "情绪调节任务").head(EmotionalRegulationExcel.class).build();
excelWriter.write(emotionalRegulationExcelList, writeSheet2);
excelWriter.finish();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.getOutputStream().flush();
response.getOutputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
经过多线程优化,时间由原来的两分钟,缩减到三分
代码简化如下:
/**
* 导出excel
*/
@GetMapping("/export/excel")
@ApiOperationSupport(order = 11)
@ApiOperation(value = "导出excel", notes = "传入gaugeRecord")
public void exportExcel(GaugeRecordEntity gaugeRecord, HttpServletResponse response) throws IOException {
ExecutorService executorService = Executors.newFixedThreadPool(3);
List excels = null;
List nbackExcels = null;
List emotionalRegulationExcelList = null;
try {
GaugeTestEntity testCondition = new GaugeTestEntity();
testCondition.setBatchId(gaugeRecord.getBatchId());
// testCondition.setSiteCode(gaugeRecord.getSiteCode());
// 查询所有人的基本信息
List allTesters = testerService.list();
// 将所有人的信息转换为 id 和 entity 的 HashMap
Map testerMap = allTesters.stream()
.collect(Collectors.toMap(TesterEntity::getIdNo, Function.identity()));
AtomicReference> excelsRef = new AtomicReference(excels);
AtomicReference> excelsRef02 = new AtomicReference(nbackExcels);
AtomicReference> excelsRef03 = new AtomicReference(emotionalRegulationExcelList);
// 使用线程池并行处理不同的数据导出任务
//输出线程号加上时间
System.out.println("当前线程" + Thread.currentThread().getId() + " " + LocalDateTime.now());
CompletableFuture task1 = CompletableFuture.runAsync(() -> {
List gauges = gaugeTestService.selectEffectiveGauge(testCondition);
List excelsAsync = gauges.stream().map(g -> {
//中间代码省略
return e;
}).collect(Collectors.toList());
excelsRef.set(excelsAsync);
//输出线程号加上时间
System.out.println("当前线程" + Thread.currentThread().getId() + " " + LocalDateTime.now());
}, executorService);
//查询工作记忆任务
CompletableFuture task2 = CompletableFuture.runAsync(() -> {
List gaugesGong = gaugeTestService.list(new QueryWrapper().lambda().eq(GaugeTestEntity::getBatchId, gaugeRecord.getBatchId()).eq(GaugeTestEntity::getTestType, 1707));
List nbackExcelsAsync = gaugesGong.stream().map(g -> {
//中间代码省略
return e;
}).collect(Collectors.toList());
excelsRef02.set(nbackExcelsAsync);
//输出线程号加上时间
System.out.println("当前线程" + Thread.currentThread().getId() + " " + LocalDateTime.now());
}, executorService);
CompletableFuture task3 = CompletableFuture.runAsync(() -> {
//查询情绪调节任务
List gaugesEmotionaTestlList = gaugeTestService.list(new QueryWrapper().lambda().eq(GaugeTestEntity::getBatchId, gaugeRecord.getBatchId()).eq(GaugeTestEntity::getTestType, 1703));
List emotionalRegulationExcelListAsync = gaugesEmotionaTestlList.stream().map(g -> {
//中间代码省略
return e;
}).collect(Collectors.toList());
//输出线程号加上时间
System.out.println(Thread.currentThread().getId() + " " + LocalDateTime.now());
excelsRef03.set(emotionalRegulationExcelListAsync);
}, executorService);
// 等待所有任务完成
CompletableFuture.allOf(task1, task2, task3).join();
// 从AtomicReference获取最终的excels列表
excels = excelsRef.get();
nbackExcels = excelsRef02.get();
emotionalRegulationExcelList = excelsRef03.get();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 销毁线程池
executorService.shutdownNow();
}
// 设置响应类型为Excel文件
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("UTF-8");
// 设置Excel文件名
response.setHeader("Content-disposition", "attachment;filename=" + "SYNL" + ".xlsx");
try {
if (!CollectionUtils.isEmpty(excels)) {
// 创建ExcelWriter并指定输出流为response.getOutputStream()
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).excelType(ExcelTypeEnum.XLSX).build();
// 写入三个sheet的数据
WriteSheet writeSheet = EasyExcel.writerSheet(0, "适应能力").head(GaugeTestExcel.class).build();
excelWriter.write(excels, writeSheet);
WriteSheet writeSheet1 = EasyExcel.writerSheet(1, "工作记忆任务").head(NBackTestExcel.class).build();
excelWriter.write(nbackExcels, writeSheet1);
WriteSheet writeSheet2 = EasyExcel.writerSheet(2, "情绪调节任务").head(EmotionalRegulationExcel.class).build();
excelWriter.write(emotionalRegulationExcelList, writeSheet2);
excelWriter.finish();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.getOutputStream().flush();
response.getOutputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
其中很重要的问题,为什么要用AtomicReference
在代码示例中,Lambda表达式中尝试修改了外部变量excels
,而excels
是在外部声明的ArrayList
,这会导致“Variable used in lambda expression should be final or effectively final”的编译错误。
为了解决这个问题,可以将excels
声明为一个AtomicReference
类型,这样就能在Lambda表达式中修改其引用指向的对象,而不改变它本身的引用。
通过将excels
声明为AtomicReference
类型,并使用AtomicReference
的set
方法来修改引用指向的对象,可以在Lambda表达式中正确地更新excels
列表,同时避免了编译错误。最后,您可以通过AtomicReference
的get
方法获取最终的excels
列表。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
盒子:页面中所有的元素(标签服务器托管网),都可以看做是一个 盒子,由盒子将页面中的元素包含在一个矩形区域内,通过盒子的视角更方便的进行页面布局 盒子模型组成:内容区域(content)、内边距区域(padding)、边框区域(border)、外边距区域(ma…