java多线程数据生成重复

发布于 2022-09-11 16:40:50 字数 3546 浏览 11 评论 0

这是我们业务中的一段代码,主要的逻辑就是将数据根据银行账号分组,每一组也就是每个银行账号起一个线程处理业务逻辑.
现在出现的问题就是有线上小概率生成重复数据,本地测试尝试还原场景,但是一直不能复现问题.

相关代码

这是入库的实体 writeOffDailyReport.也即是这个实体生成的时候重复了.

ExecutorService cachedThreadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*2);
List<Future> futures = Lists.newArrayList();
for (String value : Sets.newHashSet(multimap.keys())) {
                futures.add(cachedThreadPool.submit(() -> {
                    Thread thread = Thread.currentThread();
                    logger.info("开启一条线程," +
                            ": " + value + ",线程信息: 线程id" + thread.getId() + " 线程名" + thread.getName());
                    values.add(value);
                    List<WriteOffDailyReport> subList = Lists.newArrayList();
                    BigDecimal initAmount = BigDecimal.ZERO;
                    BigDecimal finalAmount = BigDecimal.ZERO;
                    BigDecimal bankDifferenceBD = BigDecimal.ZERO;
                    List<AnalysisBankBillVo> analysisBankBillVoList = this.getAnalysisBankBillthrowEx(MyUtils.formatNumber(value), exportDate);
                    WriteOffDailyReport reportFromAnalysisBankBill = this.setValueFromAnalysisBankBill(analysisBankBillVoList);
                    logger.info("开始遍历银行账号: " + value + " 下的所有机构核销数据");
                    for (WriteOffData writeOffDataExample : Lists.newArrayList(multimap.get(value))) {
                        logger.info("开始执行 银行账号: " + value + "下 机构: " + writeOffDataExample.getOrgName());
                        WriteOffDailyReport writeOffDailyReport = new WriteOffDailyReport();
                        writeOffDailyReport.setStatus("00");
                        this.setValueFromWriteOffData(exportDate, writeOffDataExample, writeOffDailyReport);
                        List<OrgConfig> orgConfigs = this.setValueFromOrgConig(writeOffDailyReport, orgConfigMultimap, writeOffDataExample);
                        this.setValueFromYesterDayReport(exportDate, writeOffDailyReport);
                        initAmount = new BigDecimal(writeOffDailyReport.getBankInitialBalance());
                        finalAmount = new BigDecimal(writeOffDailyReport.getBankFinalBalance());
                        bankDifferenceBD = this.computeBankDifference(bankDifferenceBD, writeOffDailyReport);
                        this.computeBusinessIncome(writeOffDailyReport);
                        this.computeBankIncomeOrPayout(writeOffDailyReport, orgConfigs);
                        this.setValueFromReportAnalysisBankBill(reportFromAnalysisBankBill, writeOffDailyReport);
                        subList.add(writeOffDailyReport);
                        logger.info("银行账号: " + value + "下 机构: " + writeOffDataExample.getOrgName() + " 完毕!");
                    }
                    logger.info("将银行账号: " + value + " 下差异汇总计算");
                    bankDifferenceBD = computeBankDifferenceExpand(bankDifferenceBD, reportFromAnalysisBankBill);
                    logger.info("开始汇总插入/更新核销日报");
                    for (WriteOffDailyReport dailyReport : subList) {
                        dailyReport.setBankDifference(MyUtils.initValue(initAmount.add(bankDifferenceBD).subtract(finalAmount).toPlainString()));
                        this.sortListFromDailyReport(batchAdd, batchUpdate, dailyReport);
                    }
                    return true;
                }));
            }
现在是将多线程去掉在跑,效率有点低.对多线程处理还是不熟悉,望指教.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

对你再特殊 2022-09-18 16:40:50
 List<AnalysisBankBillVo> analysisBankBillVoList = this.getAnalysisBankBillthrowEx(MyUtils.formatNumber(value), exportDate);
 WriteOffDailyReport reportFromAnalysisBankBill = this.setValueFromAnalysisBankBill(analysisBankBillVoList);      

应该是这里生成的逻辑问题. 没看到里边也不太好说. future是不是必须的如果不是必须的,先把这里去掉,一步一步的排查,,这种使用模式肯定是没有问题的.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文