首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >List.addAll生成的遍历列表是否在Java中生成ConcurrentModificationException?

List.addAll生成的遍历列表是否在Java中生成ConcurrentModificationException?
EN

Stack Overflow用户
提问于 2018-07-03 13:15:15
回答 2查看 96关注 0票数 1

代码后产生的ConcurrentModificationException,确保newMR在循环中不被修改,mkrs在并发环境中是线程不安全的。众所周知,List.addAll是用System.arraycopy实现的,这是JVM中固有的方法。List.addAll生成的遍历List.addAll是否在Java中生成ConcurrentModificationException

代码语言:javascript
代码运行次数:0
运行
复制
ArrayList<Foo> mkrs = mrm.getFooPush();
ArrayList<Foo> newMR = new ArrayList<Foo>(mkrs.size());
newMR.addAll(mkrs);
for (Foo mkr : newMR) {
    if (mkr != null && mkr instanceof PushRecommend) {
        PushRecommend pr = (PushRecommend) mkr;
        recommendList.add(new MayKnowMessage(pr));
    }
}

在Android机器上发布异常堆栈跟踪。请注意,(ProGuard:433)for (Foo mkr : newMR)编写的行。

代码语言:javascript
代码运行次数:0
运行
复制
java.util.ConcurrentModificationException:
java.util.ArrayList$Itr.next(ArrayList.java:837)
NewFriendManager.void loadNewFriendMsg(boolean)(ProGuard:433)
NewFriendManager.void reloadNewFriendMsg()(ProGuard:308)
NewFriendManager.boolean handleMessage(android.os.Message)(ProGuard:144)
android.os.Handler.dispatchMessage(Handler.java:106)
android.os.Looper.loop(Looper.java:232)
android.os.HandlerThread.run(HandlerThread.java:61)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-04 07:59:05

newMR.addAll(mkrs);mkrs, mrm.getFooPush()上迭代。如果在addAll期间更改了该列表,则会收到该消息。

您需要有一个并发安全列表(在getFooPush中)或一个更好的数据结构。与队列类似,如果消息是在末尾添加的,并且您被过滤(在PushRecommend上),则从前端进行过滤。

那就不需要复印了。

如前所述,Collections.synchronizedList(list)可以使原始数据结构变得安全。

票数 1
EN

Stack Overflow用户

发布于 2018-07-03 13:58:04

javadoc for ArrayList.addAll声明:

“如果在操作进行期间修改了指定的集合,则此操作的行为是未定义的。”

因此,请考虑一下:

代码语言:javascript
代码运行次数:0
运行
复制
newMR.addAll(mkrs);

addAll方法必须迭代mkrs集合。

如果mkrs在调用addAll(mkrs)时被另一个线程修改,那么如果mkrs的类型不是允许同时迭代和更新的并发集合,那么CCME是可能的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51155601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档