Java CopyOnWriteArrayList引发CurrentModificationException
当我迭代一个列表时,我偶尔会得到一个Java CopyOnWriteArrayList引发CurrentModificationException,java,multithreading,exception,collections,Java,Multithreading,Exception,Collections,当我迭代一个列表时,我偶尔会得到一个ConcurrentModificationException。谷歌搜索告诉我,这可能是因为我在另一个线程中在对列表进行迭代时更改了该列表,为了解决这个问题,我应该使用java.util.concurrent.CopyOnWriteArrayList 。。。但我已经是了 显然,我在某处做了一件非常愚蠢的事 有人知道如何诱导CopyOnWriteArrayList抛出ConcurrentModificationException?如果重要的话,我正在使用Java
ConcurrentModificationException
。谷歌搜索告诉我,这可能是因为我在另一个线程中在对列表进行迭代时更改了该列表,为了解决这个问题,我应该使用java.util.concurrent.CopyOnWriteArrayList
。。。但我已经是了
显然,我在某处做了一件非常愚蠢的事
有人知道如何诱导CopyOnWriteArrayList
抛出ConcurrentModificationException
?如果重要的话,我正在使用Java5
编辑:由于我正在使用的变异子可能很重要,我将用两种方式修改此列表:
- 在前面添加元素。(
)list.add(0,新元素);
- 使用子列表让旧项目从背面脱落。(
)list=list.subList(0,最大列表大小);
java.util.ConcurrentModificationException
at java.util.concurrent.CopyOnWriteArrayList$COWSubList.checkForComodification(Unknown Source)
at java.util.concurrent.CopyOnWriteArrayList$COWSubList.iterator(Unknown Source)
at....
java.util.ConcurrentModificationException
位于java.util.concurrent.CopyOnWriteArrayList$COWSubList.checkForComodification(未知源)
位于java.util.concurrent.CopyOnWriteArrayList$COWSubList.iterator(未知源)
在
。。。在我的代码中,它指向一个for-each循环实例化
COWSubList
似乎确实意味着我对subList
的调用是我问题的根源;我还是想知道为什么
编辑3:*facepalm*
CopyOnWriteArrayList.subList()
返回一个列表,而不是CopyOnWriteArrayList
。它返回的列表没有提供COWAL任何保护的隐含义务。这使得像这样使用subList()
删除元素是一个非常糟糕的主意
不知道这是否是我的罪魁祸首,但它非常可疑,无论如何都需要更正。CopyOnWriteArrayList.SubList如果包含列表从下面更改,则会抛出ConcurrentModificationException:
public class ListTest {
private static List<int[]> intList;
public static void main (String[] args) {
CopyOnWriteArrayList<Integer> cowal = new CopyOnWriteArrayList<Integer>();
cowal.add(1);
cowal.add(2);
cowal.add(3);
List<Integer> sub = cowal.subList(1, 2);
cowal.add(4);
sub.get(0); //throws ConcurrentModificationException
}
}
公共类列表测试{
私有静态列表;
公共静态void main(字符串[]args){
CopyOnWriteArrayList cowal=新的CopyOnWriteArrayList();
增加第(1)款;
增加(2);
增加(3);
列表子列表=cowal.子列表(1,2);
增加(4);
sub.get(0);//抛出ConcurrentModificationException
}
}
Sbodd的答案是正确的,但听起来使用CopyOnWriteArrayList而不是ArrayList只是试图掩盖错误。真正的问题是在遍历基础列表时试图修改它。您需要在代码中找到访问它的位置,并删除该用法或解决它。am确实在调用子列表,所以这可能就是它。(很难说,因为错误是在现场发生的,而不是在我的test rig.Grr上。)然而,为了让它更像我的代码,我将“cowal”改为一个简单的“List”,并且没有考虑中间的“sub”变量;我做了“cowal=cowal.subList(1,2);”。在这些情况下,代码运行时不会发生意外。subList()调用还有其他方法会引起麻烦吗?matt b:我会的,但是代码太多了,我还没有弄清楚如何将它剥离到抛出错误的地方。(然而。)如果我提出了一个简单的版本(而且答案不会跳起来打我的脸),我会发布它。仍然没有准确地在本地复制错误,但我90%确定subList()确实是我痛苦的根源。(请参阅编辑的问题了解详细原因。)感谢您为我指明了正确的方向。除了,在对基础列表进行迭代时修改它是否安全?CopyOnWriteArrayList存在的原因?这是一个老问题,但仍应注意list=list.subList(0,最大列表大小)
是一种可怕的删除元素的方法,因为子列表仍然引用包含所有元素的原始列表,因此,这会造成内存泄漏。删除末尾元素的标准方法是list.subList(MAX_list_SIZE,list.SIZE()).clear()代码>通常情况下,子列表是用于将任意列表操作应用于列表的一部分的工具,因此它们应该仅在整个操作过程中暂时保留。