线上问题整理-ConcurrentModificationException异常

项目场景:

商品改价:商品改价中通过多线程批量处理经过 Lists.partition拆分的集合对象


问题描述

商品改价中通过多线程批量处理经过 Lists.partition拆分的集合对象,发现偶尔会报

java.util.ConcurrentModificationException: nullat java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1231)at java.util.ArrayList$SubList.spliterator(ArrayList.java:1235)at java.util.Collection.stream(Collection.java:581)

代码实现逻辑

 for (Map.Entry<Integer, List<PriceHandle>> partnerIdProductId : priceHandleGroup.entrySet()) {Integer partnerId = partnerIdProductId.getKey();List<PriceHandle> priceHandles = partnerIdProductId.getValue();log.info("当前分片={},开始同步partnerId={} size={}", shardingItem, partnerId, priceHandles.size());List<List<PriceHandle>> pidsGroup = Lists.partition(priceHandles, splitSize);log.info("partnerId={},分为{}组,每组{}条", partnerId, pidsGroup.size(), splitSize);CountDownLatch countDownLatch = new CountDownLatch(pidsGroup.size());for (List<PriceHandle> priceHandlesLittle : pidsGroup) {executorService.submit(() -> {try {List<Long> productIds = priceHandlesLittle.stream().map(PriceHandle::getProductId).collect(Collectors.toList());List<ProductMapEntity> productMapEntities = productMappingAllPartnerService.getProductMapListByPartnerIdAndProductIds(partnerId, productIds);//没有映射的失败不处理List<Long> mapProductIds = productMapEntities.stream().map(ProductMapEntity::getProductId).collect(Collectors.toList());List<PriceHandle> noMapPriceHandles = priceHandlesLittle.stream().filter(e -> !mapProductIds.contains(e.getProductId())).collect(Collectors.toList());if (CollectionUtils.isNotEmpty(noMapPriceHandles)) {jingdongPriceSyncService.updateBatch(noMapPriceHandles, EventStatus.HANDLED_NO_NEED.eventStatus, "商品无映射");}priceHandlesLittle.removeAll(noMapPriceHandles);// 过滤productPool中不存在的重复品filterRepeatProductId(productMapEntities, priceHandlesLittle);if (CollectionUtils.isEmpty(productMapEntities) || CollectionUtils.isEmpty(priceHandlesLittle)) {log.info("过滤productPool中不存在的重复品");return;}PriceSyncService.synPrice(partnerId, productMapEntities, false, priceHandlesLittle);} catch (Exception e) {log.error("同步价格异常,当前处理的店铺:{}", partnerId, e);} finally {countDownLatch.countDown();}});}try {countDownLatch.await();} catch (InterruptedException e) {log.error("countDownLatch.await error", e);Thread.currentThread().interrupt();}}

原因分析:

这里需要注意的是在使用Google Guava库中的Lists.partition方法时,如果对原始列表进行了修改,则可能会导致ConcurrentModificationException异常的抛出。这是因为Lists.partition方法返回的是原始列表的视图,而不是副本。因此,如果在对视图进行操作时修改了原始列表,则会导致ConcurrentModificationException异常的抛出。
因此在我们的这段代码中 问题在于又通过拆分后的subList做了removeAll的操作


具体复现
在这里插入图片描述

解决方案:

方法1不要再for循环中基于视图 修改修改原始列表
方法2 在for循环中新建一个list对象来包装原来的list
具体实现代码

for (Map.Entry<Integer, List<PriceHandle>> partnerIdProductId : priceHandleGroup.entrySet()) {Integer partnerId = partnerIdProductId.getKey();List<PriceHandle> priceHandles = partnerIdProductId.getValue();log.info("当前分片={},开始同步partnerId={} size={}", shardingItem, partnerId, priceHandles.size());List<List<PriceHandle>> pidsGroup = Lists.partition(priceHandles, splitSize);log.info("partnerId={},分为{}组,每组{}条", partnerId, pidsGroup.size(), splitSize);CountDownLatch countDownLatch = new CountDownLatch(pidsGroup.size());for (List<PriceHandle> priceHandlesLittle : pidsGroup) {// 由于存在并发remove,需要重新赋值新ArrayList,防止ArrayList$SubList引起的ConcurrentModificationExceptionList<PriceHandle> copyPriceHandlesLittle = new ArrayList<>(priceHandlesLittle);executorService.submit(() -> {try {List<Long> productIds = copyPriceHandlesLittle.stream().map(PriceHandle::getProductId).collect(Collectors.toList());List<ProductMapEntity> productMapEntities = productMappingAllPartnerService.getProductMapListByPartnerIdAndProductIds(partnerId, productIds);//没有映射的失败不处理List<Long> mapProductIds = productMapEntities.stream().map(ProductMapEntity::getProductId).collect(Collectors.toList());List<PriceHandle> noMapPriceHandles = copyPriceHandlesLittle.stream().filter(e -> !mapProductIds.contains(e.getProductId())).collect(Collectors.toList());if (CollectionUtils.isNotEmpty(noMapPriceHandles)) {PriceSyncService.updateBatch(noMapPriceHandles, EventStatus.HANDLED_NO_NEED.eventStatus, "商品无映射");}copyPriceHandlesLittle.removeAll(noMapPriceHandles);// 过滤productPool中不存在的重复品filterRepeatProductId(productMapEntities, copyPriceHandlesLittle);if (CollectionUtils.isEmpty(productMapEntities) || CollectionUtils.isEmpty(copyPriceHandlesLittle)) {log.info("过滤productPool中不存在的重复品");return;}PriceSyncService.synJPrice(partnerId, productMapEntities, false, copyPriceHandlesLittle);} catch (Exception e) {log.error("同步价格异常,当前处理的店铺:{}", partnerId, e);} finally {countDownLatch.countDown();}});}try {countDownLatch.await();} catch (InterruptedException e) {log.error("countDownLatch.await error", e);Thread.currentThread().interrupt();}}

参考
https://blog.csdn.net/weixin_48321825/article/details/121012733?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-121012733-blog-102456357.235v38pc_relevant_default_base3&spm=1001.2101.3001.4242.1&utm_relevant_index=3

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

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

相关文章

用element-ui进行简单的商品管理

安装element-ui 项目的控制台输入npm i element-ui -S main.js import ElementUI from element-ui;//引入element-ui模块 import element-ui/lib/theme-chalk/index.css;//引入element-ui的css样式 Vue.use(ElementUI);//使用ElementUI 商品管理组件 <template><…

使用Redis实现分布式锁

说明&#xff1a;在多线程情况下&#xff0c;我们需要用到锁来控制线程对资源的访问&#xff0c;当在多线程分布式的情况下&#xff0c;如果使用synchronized (this)&#xff0c;这会在每台服务器实例上都生成一个锁对象&#xff0c;而这个锁只会对当前实例生效&#xff0c;无法…

【数字图像处理】边缘检测

边缘检测是一种图像处理技术&#xff0c;用于在图像中识别和提取物体边缘的信息&#xff0c;广泛应用于计算机视觉和图像分析领域。本文主要介绍数字图像边缘检测的基本原理&#xff0c;并记录在紫光同创 PGL22G FPGA 平台的布署与实现过程。 目录 1 边缘检测原理 2 FPGA 布署…

【工具分享】| 阅读论文神器 使用技巧 AI润色 AI翻译

文章目录 1 使用技巧1.1 功能一 即时翻译1.2 功能二 文献跳转1.3 功能三 多设备阅读1.4 功能四 小组讨论笔记共享1.5 功能五 个人文献管理 2 其他功能 超级喜欢Readpaper这一款论文阅读软件&#xff0c;吹爆他哈哈 为什么&#xff1f; 当然是他可以解决我们传统阅读论文的种种…

数据库范式1NF-4NF

码和属性 字段是对内而言的&#xff0c;private的 属性是对外而言的&#xff0c;public的 用Java中的类比喻就是一个对像里面定义了很多字段&#xff0c;一般情况下每个字段都有一组对应的getter&setter方法&#xff0c;注意到了吗&#xff0c;字段一般用private修饰&#…

HarmonyOs 4 (一) 认识HarmonyOs

目录 一 HarmonyOs 背景1.1 发展时间线1.2 背景分析1.2.1 新场景1.2.2 新挑战1.2.3 鸿蒙生态迎接挑战 二 HarmonyOS简介2.1 OpenHarmony2.2 HarmonyOS Connect2.3 HarmonyOS Next**2.4 ArkTS &#xff08;重点掌握&#xff09;****2.5 ArkUI** 三 鸿蒙生态应用核心技术理念**3.…

探索APP自动化测试工具的重要作用是什么?

随着移动应用市场的蓬勃发展&#xff0c;保障应用程序的质量和性能成为开发团队至关重要的任务。在这个背景下&#xff0c;APP自动化测试工具崭露头角&#xff0c;成为提高开发效率、减少错误率的关键工具。本文将探讨APP自动化测试工具的用途&#xff0c;以及它们在移动应用开…

mongoDB非关系型数据库学习记录

一、简介 1.1Mongodb是什么 MongoDB是一个基于分布式文件存储的数据库,官方地址https://www.mongodb.com/ 1.2数据库是什么 数据库(DataBase)是按照数据结构来组织、存储和管理数据的应用程序 1.3数据库的作用 数据库的主要作用就是管理数据,对数据进行增©、删(d)、…

大语言模型(LLMs)在 Amazon SageMaker 上的动手实践(一)

本期文章&#xff0c;我们将通过三个动手实验从浅到深地解读和演示大语言模型&#xff08;LLMs&#xff09;&#xff0c;如何结合 Amazon SageMaker 的模型部署、模型编译优化、模型分布式训练等。 实验一&#xff1a;使用 Amazon SageMaker 构建基于开源 GPT-J 模型的对话机器…

C语言错误处理之 “strerror和perror函数以及断言处理方式”

目录 前言 perror函数 strerror函数 断言处理方式 前言 在错误处理一中&#xff0c;我们解释了C语言三种处理方式中的错误号处理方式&#xff0c;这一篇我们在基于上一篇的基础上加入了strerror函数与perror函数&#xff0c;以及断言处理方式的内容...... perror函数 包…

VSCode下载安装教程+安装插件

一、vscode下载安装 1.打开 官网&#xff1a;https://code.visualstudio.com/Download 2.选择跟你电脑相对应的版本下载&#xff0c;我是win10&#xff0c;所以选择如下&#xff1a; 3.下载到你想要保存的目录下 4.下载完成后打开目录&#xff0c;双击安装包 5. 同意&#xff…

使用YOLOv8训练自己的数据集

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 拉取项目 git clone https://github.com/ultralytics/ultralytics安装依赖 cd ultralytics pip install -r requirement.txt pip instal…

【android开发-10】android中四种布局详细介绍

在Android开发中&#xff0c;常见的四种布局分别是&#xff1a;线性布局&#xff08;LinearLayout&#xff09;、相对布局&#xff08;RelativeLayout&#xff09;、帧布局&#xff08;FrameLayout&#xff09;和绝对布局&#xff08;AbsoluteLayout&#xff09;。 注意&#…

第16届中国R会议暨2023X-AGI大会开幕,和鲸科技分享ModelOps在数据科学平台中的实践与应用

11月25日&#xff0c;第 16 届中国 R 会议暨 2023 X-AGI 大会在在中国人民大学逸夫会堂拉开帷幕&#xff0c;本次会议由中国人民大学统计学院、中国人民大学应用统计科学研究中心、统计之都、原灵科技和中国商业统计学会人工智能分会&#xff08;筹&#xff09;主办&#xff0c…

React项目使用NProgress作为加载进度条

React项目使用NProgress作为加载进度条 0、效果1、react安装依赖2、使用3.进度条颜色设置 文档参考&#xff1a;https://zhuanlan.zhihu.com/p/616245086?utm_id0 0、效果 如下&#xff0c;可全局在页面顶部有一条进度条 1、react安装依赖 yarn add nprogress通过以上安装…

pytest自动化框架之allure测试报告的用例描述设置

allure测试报告的用例描述相关方法&#xff1b;如下图 allure标记用例级别severity 在做自动化测试的过程中&#xff0c;测试用例越来越多的时候&#xff0c;如果执行一轮测试发现了几个测试不通过&#xff0c;我们也希望能快速统计出缺陷的等级。 pytest结合allure框架可以对…

YOLOv5项目实战(5)— 算法模型优化和服务器部署

前言:Hello大家好,我是小哥谈。近期,作者所负责项目中的算法模型检测存在很多误报情况,为了减少这种误报情况,作者一直在不断优化算法模型。鉴于此,本节课就给大家详细介绍一下实际工作场景中如何去优化算法模型和进行部署,另外为了方便大家进行模型训练,作者在文章中提…

oracle FUNCTION(任意两个时间 之间的工作小时)

写函数计算 任意两个时间 之间的工作小时 每天工作时间&#xff08;8:00 - 20:00 共12小时&#xff09;&#xff0c;没有休息日 CREATE OR REPLACE FUNCTION SC_YD_DESI.CALCULATE_WORK_HOURS_FUNC (p_current_time IN DATE,p_order_time IN DATE ) RETURN NUMBER ASp_work_hou…

AWS Remote Control ( Wi-Fi ) on i.MX RT1060 EVK - 1 “建立开发环境”

这个系列的文章将叙述如何借由 NXP 的“evkmimxrt1060_aws_remote_control_wifi_nxp”这支 Sample Code&#xff0c;达到 NXP RT1060EVK 经由 U-Blox EVK-JODY-W263 将资讯传到 AWS 上&#xff0c;并可借由手机对 RT1060 EVK 的 LED 进行远端控制。 整体架构如下图所示&#x…

道可云会展元宇宙平台全新升级,打造3D沉浸式展会新模式

随着VR虚拟现实、人工智能、虚拟数字人等元宇宙技术的快速发展&#xff0c;各个行业正试图通过元宇宙技术寻求新的发展突破口&#xff0c;会展行业也不例外。会展作为经贸领域的重要产业形态&#xff0c;越来越多的企业和组织开始寻求通过元宇宙技术为展会赋能&#xff0c;以满…