java利用多线程,线程池加快任务处理时间,等待所有线程结束,数据统一处理

news/2024/6/24 7:31:19/文章来源:https://blog.csdn.net/weixin_42759398/article/details/137234469

遇到了业务上处理很慢的情况,都可以用多线程解决,这是原先未优化的代码

/*** 导出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<TesterEntity> allTesters = testerService.list();
// 将所有人的信息转换为 id 和 entity 的 HashMapMap<String, TesterEntity> testerMap = allTesters.stream().collect(Collectors.toMap(TesterEntity::getIdNo, Function.identity()));List<GaugeTestEntity> gauges = gaugeTestService.selectEffectiveGauge(testCondition);List<GaugeTestExcel> 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 ? 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());//查询工作记忆任务List<GaugeTestEntity> gaugesGong = gaugeTestService.list(new QueryWrapper<GaugeTestEntity>().lambda().eq(GaugeTestEntity::getBatchId, gaugeRecord.getBatchId()).eq(GaugeTestEntity::getTestType, 1707));List<NBackTestExcel> 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<Integer, List<NBlackJsonVO>> nbackListHashMap = new HashMap<>();ArrayList<NBlackJsonVO> nBlackJsonVOS = new ArrayList<>();//JSONArray jsonArrayNBack = JSON.parseArray(g.getUserAnswer());//一共160个for (int i = 0; i < jsonArrayNBack.size(); i++) {JSONObject jsonObject = jsonArrayNBack.getJSONObject(i);String SDTTask1 = jsonObject.getString("SDTTask1");//任务一的信号检测论指标:1击中(应该按左键,被试按了左键: targetTask1=1 & respLeft=1),2漏报(应该按左键,被试没按左键:targetTask1=1 & respLeft = 0),3正确拒斥(无需按左键,被试没按左键:targetTask1=0 & respLeft =0),4虚报(无需按左键,被试按了左键:targetTask1=0 & respLeft=1)String block0Mubiao = jsonObject.getString("block0Mubiao");//block0的目标值String blockNum = jsonObject.getString("blockNum");//block编号  0-7  一共八个String itemTask1 = jsonObject.getString("itemTask1");//刺激的位置String level = jsonObject.getString("level");//当前block的难度等级:也即n-back任务的n值String respLeft = jsonObject.getString("respLeft");//被试的作答,是否按左键(即修改后的“位置”按钮,原来的“A”按钮):1,有按左键;0,没有按左键String targetTask1 = jsonObject.getString("targetTask1");//刺激是否是需要用户按键的目标刺激:0,不是;1,是String timer = jsonObject.getString("timer");//反应时String trainNum = jsonObject.getString("trainNum");//训练次数编号 1-160  最高160  有多少数就循环多少次String trialNum = jsonObject.getString("trialNum");//每个block内的trial编号 0-19  最高19   20个就清零NBlackJsonVO nBlackJsonVO = new NBlackJsonVO();nBlackJsonVO.setBlockNum(blockNum);nBlackJsonVO.setTimer(timer);nBlackJsonVO.setBlock0Mubiao(block0Mubiao);nBlackJsonVO.setItemTask1(itemTask1);nBlackJsonVO.setLevel(level);nBlackJsonVO.setTargetTask1(targetTask1);nBlackJsonVO.setTrainNum(trainNum);nBlackJsonVO.setTrialNum(trialNum);nBlackJsonVO.setRespLeft(respLeft);nBlackJsonVO.setSDTTask1(SDTTask1);nBlackJsonVOS.add(nBlackJsonVO);// 打印或处理这些字段的数据//每20个 建立一个list 然后向 nbackListHashMap加一个valueif ((i + 1) % 20 == 0) {//每20个清空nbackListHashMap.put(Integer.parseInt(blockNum), nBlackJsonVOS);nBlackJsonVOS = new ArrayList<>();}}//循环遍历我的mapint totalAccuracyOfVisualNumber = 0;ArrayList<Integer> totalReactionTimeList = new ArrayList<>();// 用于全部Block记录每轮的反应时间for (Map.Entry<Integer, List<NBlackJsonVO>> entry : nbackListHashMap.entrySet()) {// 创建一个数组来存储每轮的反应时间ArrayList<Integer> reactionTimeList = new ArrayList<>();// 用于记录每轮的反应时间int omissionErrorNumber = 0;//漏报次数  为2的int incorrectClassificationsNumber = 0; //错误次数 为4的int accuracyNnmber = 0;//其他Integer visualTestCategory = 1;//视觉分类任务Integer blockNum = null;Integer difficultyLevel = null;List<NBlackJsonVO> nabckList = entry.getValue();for (NBlackJsonVO nBlackJsonVO : nabckList) {String timer = nBlackJsonVO.getTimer();// 获取当前轮的 blockNumblockNum = Integer.parseInt(nBlackJsonVO.getBlockNum());// 获取难度等级difficultyLevel = Integer.parseInt(nBlackJsonVO.getLevel());// 将反应时间转换为 BigDecimalif (timer != null && !timer.isEmpty()) {// 将字符串转换为 BigDecimalBigDecimal 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<GaugeTestEntity> gaugesEmotionaTestlList = gaugeTestService.list(new QueryWrapper<GaugeTestEntity>().lambda().eq(GaugeTestEntity::getBatchId, gaugeRecord.getBatchId()).eq(GaugeTestEntity::getTestType, 1703));List<EmotionalRegulationExcel> 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<Integer> aversiveNums = new ArrayList<>();ArrayList<Integer> neutralNums = new ArrayList<>();for (int i = 0; i < jsonArrayQing.size(); i++) {JSONObject jsonObject = jsonArrayQing.getJSONObject(i);Integer blockNum = jsonObject.getInteger("blockNum");//block编号Integer feel = jsonObject.getInteger("feel");//感受评分String lookType = jsonObject.getString("lookType");//look or lessString picType = jsonObject.getString("picType");//A or NString picName = jsonObject.getString("picName");//图片名称String showTime = jsonObject.getString("showTime");//显示时间String timer = jsonObject.getString("timer");//用时Integer trialNum = jsonObject.getInteger("trialNum");//block编号// 打印或处理这些字段的数据EmotionalExcelVO emotionalExcelVO = new EmotionalExcelVO();emotionalExcelVO.setBlock(blockNum);emotionalExcelVO.setEmotionalAssessmentScore(feel);emotionalExcelVO.setPictureValenceAndSerialNumber(picName);emotionalExcelVO.setEmotionalRegulationStrategy(picType.equals("look") ? 1 : 2);emotionalExcelVO.setTrial(trialNum);//自然情绪反应得分 计算【20张厌恶图片观察得分的平均值】-【20张中性图片观察得分的平均值】,得分范围0-100if (picType.equals("Aversive")){aversiveNums.add(feel);}else {neutralNums.add(feel);}//情绪调节能力得分  计算【20张厌恶图片观察得分的平均值】-【35张厌恶图片改变得分的平均值】this.fillFieldsForQing(e, emotionalExcelVO);}//自然情绪反应得分List<Integer> aversiveNum_0_20 = aversiveNums.subList(0, 20);List<Integer> neutralNum_0_20 = neutralNums.subList(0, 20);List<Integer> 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<TesterEntity> allTesters = testerService.list();
// 将所有人的信息转换为 id 和 entity 的 HashMapMap<String, TesterEntity> testerMap = allTesters.stream().collect(Collectors.toMap(TesterEntity::getIdNo, Function.identity()));List<GaugeTestExcel> excels = null;List<NBackTestExcel> nbackExcels= null;List<EmotionalRegulationExcel> emotionalRegulationExcelList = null;AtomicReference<List<GaugeTestExcel>> excelsRef = new AtomicReference<>(excels);AtomicReference<List<NBackTestExcel>> excelsRef02 = new AtomicReference<>(nbackExcels);AtomicReference<List<EmotionalRegulationExcel>> excelsRef03 = new AtomicReference<>(emotionalRegulationExcelList);// 使用线程池并行处理不同的数据导出任务//输出线程号加上时间System.out.println("当前线程"+Thread.currentThread().getId() + " " + LocalDateTime.now());ExecutorService executorService = Executors.newFixedThreadPool(3);CompletableFuture<Void> task1 = CompletableFuture.runAsync(() -> {List<GaugeTestEntity> gauges = gaugeTestService.selectEffectiveGauge(testCondition);List<GaugeTestExcel>   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<Void> task2 = CompletableFuture.runAsync(() -> {List<GaugeTestEntity> gaugesGong = gaugeTestService.list(new QueryWrapper<GaugeTestEntity>().lambda().eq(GaugeTestEntity::getBatchId, gaugeRecord.getBatchId()).eq(GaugeTestEntity::getTestType, 1707));List<NBackTestExcel> 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<Integer, List<NBlackJsonVO>> nbackListHashMap = new HashMap<>();ArrayList<NBlackJsonVO> nBlackJsonVOS = new ArrayList<>();//JSONArray jsonArrayNBack = JSON.parseArray(g.getUserAnswer());//一共160个for (int i = 0; i < jsonArrayNBack.size(); i++) {JSONObject jsonObject = jsonArrayNBack.getJSONObject(i);String SDTTask1 = jsonObject.getString("SDTTask1");//任务一的信号检测论指标:1击中(应该按左键,被试按了左键: targetTask1=1 & respLeft=1),2漏报(应该按左键,被试没按左键:targetTask1=1 & respLeft = 0),3正确拒斥(无需按左键,被试没按左键:targetTask1=0 & respLeft =0),4虚报(无需按左键,被试按了左键:targetTask1=0 & respLeft=1)String block0Mubiao = jsonObject.getString("block0Mubiao");//block0的目标值String blockNum = jsonObject.getString("blockNum");//block编号  0-7  一共八个String itemTask1 = jsonObject.getString("itemTask1");//刺激的位置String level = jsonObject.getString("level");//当前block的难度等级:也即n-back任务的n值String respLeft = jsonObject.getString("respLeft");//被试的作答,是否按左键(即修改后的“位置”按钮,原来的“A”按钮):1,有按左键;0,没有按左键String targetTask1 = jsonObject.getString("targetTask1");//刺激是否是需要用户按键的目标刺激:0,不是;1,是String timer = jsonObject.getString("timer");//反应时String trainNum = jsonObject.getString("trainNum");//训练次数编号 1-160  最高160  有多少数就循环多少次String trialNum = jsonObject.getString("trialNum");//每个block内的trial编号 0-19  最高19   20个就清零NBlackJsonVO nBlackJsonVO = new NBlackJsonVO();nBlackJsonVO.setBlockNum(blockNum);nBlackJsonVO.setTimer(timer);nBlackJsonVO.setBlock0Mubiao(block0Mubiao);nBlackJsonVO.setItemTask1(itemTask1);nBlackJsonVO.setLevel(level);nBlackJsonVO.setTargetTask1(targetTask1);nBlackJsonVO.setTrainNum(trainNum);nBlackJsonVO.setTrialNum(trialNum);nBlackJsonVO.setRespLeft(respLeft);nBlackJsonVO.setSDTTask1(SDTTask1);nBlackJsonVOS.add(nBlackJsonVO);// 打印或处理这些字段的数据//每20个 建立一个list 然后向 nbackListHashMap加一个valueif ((i + 1) % 20 == 0) {//每20个清空nbackListHashMap.put(Integer.parseInt(blockNum), nBlackJsonVOS);nBlackJsonVOS = new ArrayList<>();}}//循环遍历我的mapint totalAccuracyOfVisualNumber = 0;ArrayList<Integer> totalReactionTimeList = new ArrayList<>();// 用于全部Block记录每轮的反应时间for (Map.Entry<Integer, List<NBlackJsonVO>> entry : nbackListHashMap.entrySet()) {// 创建一个数组来存储每轮的反应时间ArrayList<Integer> reactionTimeList = new ArrayList<>();// 用于记录每轮的反应时间int omissionErrorNumber = 0;//漏报次数  为2的int incorrectClassificationsNumber = 0; //错误次数 为4的int accuracyNnmber = 0;//其他Integer visualTestCategory = 1;//视觉分类任务Integer blockNum = null;Integer difficultyLevel = null;List<NBlackJsonVO> nabckList = entry.getValue();for (NBlackJsonVO nBlackJsonVO : nabckList) {String timer = nBlackJsonVO.getTimer();// 获取当前轮的 blockNumblockNum = Integer.parseInt(nBlackJsonVO.getBlockNum());// 获取难度等级difficultyLevel = Integer.parseInt(nBlackJsonVO.getLevel());// 将反应时间转换为 BigDecimalif (timer != null && !timer.isEmpty()) {// 将字符串转换为 BigDecimalBigDecimal 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<Void> task3 = CompletableFuture.runAsync(() -> {//查询情绪调节任务List<GaugeTestEntity> gaugesEmotionaTestlList = gaugeTestService.list(new QueryWrapper<GaugeTestEntity>().lambda().eq(GaugeTestEntity::getBatchId, gaugeRecord.getBatchId()).eq(GaugeTestEntity::getTestType, 1703));List<EmotionalRegulationExcel>    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<Integer> aversiveNums = new ArrayList<>();ArrayList<Integer> neutralNums = new ArrayList<>();for (int i = 0; i < jsonArrayQing.size(); i++) {JSONObject jsonObject = jsonArrayQing.getJSONObject(i);Integer blockNum = jsonObject.getInteger("blockNum");//block编号Integer feel = jsonObject.getInteger("feel");//感受评分String lookType = jsonObject.getString("lookType");//look or lessString picType = jsonObject.getString("picType");//A or NString picName = jsonObject.getString("picName");//图片名称String showTime = jsonObject.getString("showTime");//显示时间String timer = jsonObject.getString("timer");//用时Integer trialNum = jsonObject.getInteger("trialNum");//block编号// 打印或处理这些字段的数据EmotionalExcelVO emotionalExcelVO = new EmotionalExcelVO();emotionalExcelVO.setBlock(blockNum);emotionalExcelVO.setEmotionalAssessmentScore(feel);emotionalExcelVO.setPictureValenceAndSerialNumber(picName);emotionalExcelVO.setEmotionalRegulationStrategy(picType.equals("look") ? 1 : 2);emotionalExcelVO.setTrial(trialNum);//自然情绪反应得分 计算【20张厌恶图片观察得分的平均值】-【20张中性图片观察得分的平均值】,得分范围0-100if (picType.equals("Aversive")) {aversiveNums.add(feel);} else {neutralNums.add(feel);}//情绪调节能力得分  计算【20张厌恶图片观察得分的平均值】-【35张厌恶图片改变得分的平均值】this.fillFieldsForQing(e, emotionalExcelVO);}//自然情绪反应得分List<Integer> aversiveNum_0_20 = aversiveNums.subList(0, 20);List<Integer> neutralNum_0_20 = neutralNums.subList(0, 20);List<Integer> 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<GaugeTestExcel> excels = null;List<NBackTestExcel> nbackExcels = null;List<EmotionalRegulationExcel> emotionalRegulationExcelList = null;try {GaugeTestEntity testCondition = new GaugeTestEntity();testCondition.setBatchId(gaugeRecord.getBatchId());
//		testCondition.setSiteCode(gaugeRecord.getSiteCode());// 查询所有人的基本信息List<TesterEntity> allTesters = testerService.list();
// 将所有人的信息转换为 id 和 entity 的 HashMapMap<String, TesterEntity> testerMap = allTesters.stream().collect(Collectors.toMap(TesterEntity::getIdNo, Function.identity()));AtomicReference<List<GaugeTestExcel>> excelsRef = new AtomicReference<>(excels);AtomicReference<List<NBackTestExcel>> excelsRef02 = new AtomicReference<>(nbackExcels);AtomicReference<List<EmotionalRegulationExcel>> excelsRef03 = new AtomicReference<>(emotionalRegulationExcelList);// 使用线程池并行处理不同的数据导出任务//输出线程号加上时间System.out.println("当前线程" + Thread.currentThread().getId() + " " + LocalDateTime.now());CompletableFuture<Void> task1 = CompletableFuture.runAsync(() -> {List<GaugeTestEntity> gauges = gaugeTestService.selectEffectiveGauge(testCondition);List<GaugeTestExcel> excelsAsync = gauges.stream().map(g -> {//中间代码省略return e;}).collect(Collectors.toList());excelsRef.set(excelsAsync);
//输出线程号加上时间System.out.println("当前线程" + Thread.currentThread().getId() + " " + LocalDateTime.now());}, executorService);//查询工作记忆任务CompletableFuture<Void> task2 = CompletableFuture.runAsync(() -> {List<GaugeTestEntity> gaugesGong = gaugeTestService.list(new QueryWrapper<GaugeTestEntity>().lambda().eq(GaugeTestEntity::getBatchId, gaugeRecord.getBatchId()).eq(GaugeTestEntity::getTestType, 1707));List<NBackTestExcel> nbackExcelsAsync = gaugesGong.stream().map(g -> {//中间代码省略return e;}).collect(Collectors.toList());excelsRef02.set(nbackExcelsAsync);
//输出线程号加上时间System.out.println("当前线程" + Thread.currentThread().getId() + " " + LocalDateTime.now());}, executorService);CompletableFuture<Void> task3 = CompletableFuture.runAsync(() -> {//查询情绪调节任务List<GaugeTestEntity> gaugesEmotionaTestlList = gaugeTestService.list(new QueryWrapper<GaugeTestEntity>().lambda().eq(GaugeTestEntity::getBatchId, gaugeRecord.getBatchId()).eq(GaugeTestEntity::getTestType, 1703));List<EmotionalRegulationExcel> 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类型,并使用AtomicReferenceset方法来修改引用指向的对象,可以在Lambda表达式中正确地更新excels列表,同时避免了编译错误。最后,您可以通过AtomicReferenceget方法获取最终的excels列表。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_1034182.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 动静态库的制作,使用和加载

Linux 动静态库的制作,使用和加载 一.前置说明1.mylib.h2.mylib.c3.mymath.h mymath.c4.如何制作库 二.动静态库的制作1.静态库的制作1.制作2.使用一下静态库,验证是否成功打包 2.动态库的制作1.编译.c源文件文件生成.o目标文件2.打包生成动态库3.编写makefile文件,自动化制作动…

Spring 整合 Log4j2日志框架

1. Log4j2日志概述 在项目开发中&#xff0c;日志十分的重要&#xff0c;不管是记录运行情况还是定位线上问题&#xff0c;都离不开对日志的分析。日志记录了系统行为的时间、地点、状态等相关信息&#xff0c;能够帮助我们了解并监控系统状态&#xff0c;在发生错误或者接近某…

Go语言流程控制

条件语句需要开发者通过指定一个或多个条件&#xff0c;并通过测试条件是否为true来决定是否执行指定语句&#xff0c;并在条件为false的情况下执行另外的语句。 Go语言提供了一下几种条件判断语句 一. 条件语句if 1.1 if语句由一个布尔表达式后紧跟一个或多个语句组成 语法&a…

如何在Portainer中创建Nginx服务并搭建静态站点实现公网访问本地网站

文章目录 前言1. 安装Portainer1.1 访问Portainer Web界面 2. 使用Portainer创建Nginx容器3. 将Web静态站点实现公网访问4. 配置Web站点公网访问地址4.1公网访问Web站点 5. 固定Web静态站点公网地址6. 固定公网地址访问Web静态站点 前言 Portainer是一个开源的Docker轻量级可视…

牛牛排队伍

有 n 个人排队&#xff0c;1 号排在 2 号前面&#xff0c;2 号排在 3 号前面&#xff0c;…&#xff0c;以此类推 n−1 号排在 n 号前面。在这个过程中&#xff0c;偶尔老师会把某个人叫走&#xff0c;叫走之后这个人就离开了队伍&#xff0c;假设本来 a排在 b 前面&#xff0c…

SiameseRPN原理详解(个人学习笔记)

参考资源&#xff1a; 视觉目标跟踪SiamRPNSiameseRPN详解CVPR2018视觉目标跟踪之 SiameseRPN 目录&#xff09; 1. 模型架构1.1 Siamese Network1.2 RPN 2. 模型训练2.1 损失函数2.2 端到端训练2.3 正负样本选择 3. 跟踪阶段总结 SiamRPN是在SiamFC的基础上进行改进而得到的一…

Adobe ColdFusion 任意文件读取漏洞复现(CVE-2024-20767)

0x01 产品简介 Adobe ColdFusion是美国奥多比(Adobe)公司的一套快速应用程序开发平台。该平台包括集成开发环境和脚本语言,将可扩展、改变游戏规则且可靠的产品的愿景变为现实。 0x02 漏洞概述 由于 Adobe ColdFusion 的访问控制不当,未经身份认证的远程攻击者可以构造恶…

Ubuntu20.04安装MatlabR2018a

一、安装包 安装包下载链接 提取码&#xff1a;kve2 网上相关教程很多&#xff0c;此处仅作为安装软件记录&#xff0c;方便后续软件重装&#xff0c;大家按需取用。 二、安装 1. 相关文件一览 下载并解压文件后&#xff0c;如下图所示&#xff1a; 2. 挂载镜像并安装 2…

服务器被CC攻击之后怎么办?

1.取消域名绑定取消域名绑定后Web服务器的CPU能够马上恢复正常状态&#xff0c;通过IP进行访问连接一切正常。但是不足之处也很明显&#xff0c;取消或者更改域名对于别人的访问带来了不变&#xff0c;另外&#xff0c;对于针对IP的CC攻击它是无效的&#xff0c;就算更换域名攻…

【WEEK5】 【DAY5】DML语言【中文版】

2024.3.29 Friday 目录 3.DML语言3.1.外键&#xff08;了解&#xff09;3.1.1.概念3.1.2.作用3.1.3.添加&#xff08;书写&#xff09;外键的几种方法3.1.3.1.创建表时直接在主动引用的表里写&#xff08;被引用的表的被引用的部分&#xff09;3.1.3.2.先创建表后修改表以添加…

unity 打包安卓错误汇集

Failed to find target with hash string "android-34’ in: D:Pr 他说找不到sdk34level的我用as打开后卸载又重装&#xff0c;最后解决了 我放到Plugins/Android/下面的Java代码没有被编译 这个不知道为什么。我故意把代码写的有问题&#xff0c;会报错那种&#xff…

认识docker

认识docker 1.镜像和容器2.MySQL镜像命令解读3.docker常用命令4.数据挂载&#xff08;1&#xff09;数据卷&#xff08;2&#xff09;本地目录挂载 5.自定义镜像&#xff08;1&#xff09;Dockerfile 6.容器网络互连7、参考 1.镜像和容器 当我们利用 Docker 安装应用时&#x…

面试题 之 webpack

1.说说你对webpack理解&#xff1f;解决什么问题&#xff1f; Webpack 是实现前端项目的模块化&#xff0c;用于现代 JavaScript 应用程序的静态模块打包工具&#xff0c;被webpack 直接引用的资源打包进 bunde.js的资源&#xff0c;当webpack 处理应用程序时,它会在内部构建一…

Mysql数据库:故障分析与配置优化

目录 前言 一、Mysql逻辑架构图 二、Mysql单实例常见故障 1、无法通过套接字连接到本地MySQL服务器 2、用户rootlocalhost访问被拒绝 3、远程连接数据库时连接很慢 4、无法打开以MYI结尾的索引文件 5、超出最大连接错误数量限制 6、连接过多 7、配置文件/etc/my.cnf权…

SmartChart的部署以及可能遇见的报错解决方案

简介 数据可视化是一种将数据转化为图形的技术&#xff0c;可以帮助人们更好地理解和分析数据。但是&#xff0c;传统的数据可视化开发往往需要编写大量的代码&#xff0c;或者使用复杂的拖拽工具&#xff0c;不仅耗时耗力&#xff0c;而且难以实现个性化的需求。有没有一种更…

《VMamba》论文笔记

原文链接&#xff1a; [2401.10166] VMamba: Visual State Space Model (arxiv.org) 原文笔记&#xff1a; What&#xff1a; VMamba: Visual State Space Model Why&#xff1a; 多年以来CNN和VIT作为视觉特征提取的主流框架 CNN具有模型简单&#xff0c;共享权重&…

The Google File System [SOSP‘03] 论文阅读笔记

原论文&#xff1a;The Google File System 1. Introduction 组件故障是常态而非例外 因此&#xff0c;我们需要持续监控、错误检测、容错和自动恢复&#xff01; 按照传统标准&#xff0c;文件数量巨大大多数文件都是通过添加新数据而不是覆盖现有数据来改变的&#xff0c;因…

近屿智能独家发布行业领先的AIGC学习路径图

近日来“人工智能即将取代大量人类工作”的话题愈演愈烈&#xff0c;在CCTV-13的《两会你我他》访谈节目中&#xff0c;众多专家也围绕这一议题展开了深入的讨论&#xff0c;AI不会取代你的工作&#xff0c;会取代你的是懂AI技术的人。李强总理在访谈中也强调了推动"人工智…

加密/ 解密 PDF:使用Python为PDF文档设置、移除密码

在数字化时代&#xff0c;文档的安全性变得越来越重要。特别是对于包含敏感信息的PDF文件&#xff0c;确保其不被未经授权的人员访问或修改是至关重要的。本文将介绍如何使用Python在PDF文档中设置密码&#xff0c;以及如何移除已经设置的密码。 目录 PDF加密基础知识 Pytho…

利用 docker 实现JMeter分布式压测

为什么需要分布式&#xff1f; 在工作中经常需要对一些关键接口做高QPS的压测&#xff0c;JMeter是由Java 语言开发&#xff0c;没创建一个线程&#xff08;虚拟用户&#xff09;&#xff0c;JVM默认会为每个线程分配1M的堆栈内存空间。受限于单台试压机的配置很难实现太高的并…