Java List和递归导致并发修改异常
以下函数递归地遍历列表并将其始终除以一半并对子列表执行某些操作。当列表大小为 2 时,递归会中断。我知道如果在迭代列表时更改列表,则会发生并发修改异常。但我不使用迭代,它仍然发生:
private static List<ParticipantSlot> divide(List<ParticipantSlot> list) {
int n = list.size();
//do something
if (n>2){
List<ParticipantSlot> l = divide(list.subList(0, n/2-1));
List<ParticipantSlot> r= divide(list.subList(n/2, n));
l.addAll(r);
return l;
}else{
return list;
}
}
The following function walks recursively through a list and divide it always by half and do something with the sublists. The recursion breaks when the listsize is 2. I know a concurrent modification exception occurs if I change the list when I iterate over it. But I don't use iterations and it still happens:
private static List<ParticipantSlot> divide(List<ParticipantSlot> list) {
int n = list.size();
//do something
if (n>2){
List<ParticipantSlot> l = divide(list.subList(0, n/2-1));
List<ParticipantSlot> r= divide(list.subList(n/2, n));
l.addAll(r);
return l;
}else{
return list;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您正在使用
addAll()
它将迭代您在参数中提供的集合。现在,subList
仅返回原始列表上的视图,因此您尝试将值添加到原始列表的视图上,并迭代原始列表的不同部分同时列出。砰。如果您每次都创建子列表的副本,它应该可以工作 - 尽管效率相当低。
You're using
addAll()
which will iterate over the collection you provide in the argument. NowsubList
only returns a view onto the original list, so you're trying to add values onto a view of the original list, and iterate over a different part of the original list at the same time. Bang.If you created a copy of the sublist each time, it should work - although it'll be pretty inefficient.
您会收到并发修改异常,因为子列表由原始列表支持:
如果您想避免异常,请在修改第一个子列表之前复制它。
You get a concurrent modification exception because sublist is backed by the original list:
If you would like to avoid an exception, make a copy of the first sublist before modifying it.
如果您使用的是 ArrayList,您可能需要将其更改为 CopyOnWriteArrayList,或 ConcurrentLinkedQueue。
如果您处于多线程环境中,您将需要在数组周围放置一个
synchronized
。希望有帮助。
If you are using ArrayList, you may want to change it to a CopyOnWriteArrayList, or ConcurrentLinkedQueue.
If you are on a Multi-thread environment, you will want to put a
synchronized
around your Array.Hope it helps.