java - 遍历 List.addAll 生成的 List 会在 Java 中产生 ConcurrentModificationException 吗?
问题描述
下面生成的代码贴ConcurrentModificationException
, newMR
确保不会在循环中修改,mkrs
在并发环境中是线程不安全的。众所周知,JVM中的内在方法List.addAll
是由哪个实现的。System.arraycopy
遍历是否由Java 中List
的生成生成List.addAll
?ConcurrentModificationException
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)
写入的行。
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)
解决方案
状态的javadocArrayList.addAll
:
“如果在操作进行时修改了指定的集合,则此操作的行为未定义。”
所以考虑一下:
newMR.addAll(mkrs);
该addAll
方法将不得不迭代mkrs
集合。
如果mkrs
在您调用 时被另一个线程修改,那么如果 的类型不是允许同时迭代和更新的并发集合addAll(mkrs)
,则 CCME 是可能的。mkrs
推荐阅读
- python - 如何在python中获取另一个函数的预期参数?
- java - Spring REST - 正在下载损坏/空白文件
- jenkins - 如何使用声明式 Jenkinsfile 构建 docker 镜像
- sqlite - 离子 executeSql 不起作用
- selenium - 如何在使用 seleniumlibrary 的机器人框架测试用例中多次运行特定关键字?
- java - 在 LibGDX 中创建一个 TextField
- java - 是否有一个类来保存文件(内容和名称)
- .net - 如何从 ServiceStack API 返回 XmlDocument 作为响应
- unit-testing - 如何使用相对路径在jsdom中加载html文件?
- aurelia - 电子邮件验证通过,无需域扩展